blob: 629d2bc9a5d19516bc0aae43d46995c6a847dcd1 [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
41
42
43namespace android {
44
45
Sungjoong Kang9dd63e12012-07-24 00:25:51 +090046void m_savePostView(const char *fname, uint8_t *buf, uint32_t size)
47{
48 int nw;
49 int cnt = 0;
50 uint32_t written = 0;
51
52 ALOGD("opening file [%s], address[%x], size(%d)", fname, (unsigned int)buf, size);
53 int fd = open(fname, O_RDWR | O_CREAT, 0644);
54 if (fd < 0) {
55 ALOGE("failed to create file [%s]: %s", fname, strerror(errno));
56 return;
57 }
58
59 ALOGD("writing %d bytes to file [%s]", size, fname);
60 while (written < size) {
61 nw = ::write(fd, buf + written, size - written);
62 if (nw < 0) {
63 ALOGE("failed to write to file %d [%s]: %s",written,fname, strerror(errno));
64 break;
65 }
66 written += nw;
67 cnt++;
68 }
69 ALOGD("done writing %d bytes to file [%s] in %d passes",size, fname, cnt);
70 ::close(fd);
71}
72
Jiyoung Shinc15a6b02012-06-05 01:08:14 -070073int get_pixel_depth(uint32_t fmt)
74{
75 int depth = 0;
76
77 switch (fmt) {
78 case V4L2_PIX_FMT_JPEG:
79 depth = 8;
80 break;
81
82 case V4L2_PIX_FMT_NV12:
83 case V4L2_PIX_FMT_NV21:
84 case V4L2_PIX_FMT_YUV420:
85 case V4L2_PIX_FMT_YVU420M:
86 case V4L2_PIX_FMT_NV12M:
87 case V4L2_PIX_FMT_NV12MT:
88 depth = 12;
89 break;
90
91 case V4L2_PIX_FMT_RGB565:
92 case V4L2_PIX_FMT_YUYV:
93 case V4L2_PIX_FMT_YVYU:
94 case V4L2_PIX_FMT_UYVY:
95 case V4L2_PIX_FMT_VYUY:
96 case V4L2_PIX_FMT_NV16:
97 case V4L2_PIX_FMT_NV61:
98 case V4L2_PIX_FMT_YUV422P:
99 case V4L2_PIX_FMT_SBGGR10:
100 case V4L2_PIX_FMT_SBGGR12:
101 case V4L2_PIX_FMT_SBGGR16:
102 depth = 16;
103 break;
104
105 case V4L2_PIX_FMT_RGB32:
106 depth = 32;
107 break;
108 default:
109 ALOGE("Get depth failed(format : %d)", fmt);
110 break;
111 }
112
113 return depth;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900114}
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700115
116int cam_int_s_fmt(node_info_t *node)
117{
118 struct v4l2_format v4l2_fmt;
119 unsigned int framesize;
120 int ret;
121
122 memset(&v4l2_fmt, 0, sizeof(struct v4l2_format));
123
124 v4l2_fmt.type = node->type;
125 framesize = (node->width * node->height * get_pixel_depth(node->format)) / 8;
126
127 if (node->planes >= 1) {
128 v4l2_fmt.fmt.pix_mp.width = node->width;
129 v4l2_fmt.fmt.pix_mp.height = node->height;
130 v4l2_fmt.fmt.pix_mp.pixelformat = node->format;
131 v4l2_fmt.fmt.pix_mp.field = V4L2_FIELD_ANY;
132 } else {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900133 ALOGE("%s:S_FMT, Out of bound : Number of element plane",__FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700134 }
135
136 /* Set up for capture */
137 ret = exynos_v4l2_s_fmt(node->fd, &v4l2_fmt);
138
139 if (ret < 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900140 ALOGE("%s: exynos_v4l2_s_fmt fail (%d)",__FUNCTION__, ret);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700141
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700142 node->streamOn = false;
143
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700144 return ret;
145}
146
147int cam_int_reqbufs(node_info_t *node)
148{
149 struct v4l2_requestbuffers req;
150 int ret;
151
152 req.count = node->buffers;
153 req.type = node->type;
154 req.memory = node->memory;
155
156 ret = exynos_v4l2_reqbufs(node->fd, &req);
157
158 if (ret < 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900159 ALOGE("%s: VIDIOC_REQBUFS (fd:%d) failed (%d)",__FUNCTION__,node->fd, ret);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700160
161 return req.count;
162}
163
164int cam_int_qbuf(node_info_t *node, int index)
165{
166 struct v4l2_buffer v4l2_buf;
167 struct v4l2_plane planes[VIDEO_MAX_PLANES];
168 int i;
169 int ret = 0;
170
171 v4l2_buf.m.planes = planes;
172 v4l2_buf.type = node->type;
173 v4l2_buf.memory = node->memory;
174 v4l2_buf.index = index;
175 v4l2_buf.length = node->planes;
176
177 for(i = 0; i < node->planes; i++){
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900178 v4l2_buf.m.planes[i].m.fd = (int)(node->buffer[index].fd.extFd[i]);
179 v4l2_buf.m.planes[i].length = (unsigned long)(node->buffer[index].size.extS[i]);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700180 }
181
182 ret = exynos_v4l2_qbuf(node->fd, &v4l2_buf);
183
184 if (ret < 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900185 ALOGE("%s: cam_int_qbuf failed (index:%d)(ret:%d)",__FUNCTION__, index, ret);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700186
187 return ret;
188}
189
190int cam_int_streamon(node_info_t *node)
191{
192 enum v4l2_buf_type type = node->type;
193 int ret;
194
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700195 if (node->streamOn)
196 return 0;
197
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700198 ret = exynos_v4l2_streamon(node->fd, type);
199
200 if (ret < 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900201 ALOGE("%s: VIDIOC_STREAMON failed (%d)",__FUNCTION__, ret);
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700202 else
203 node->streamOn = true;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700204
205 ALOGV("On streaming I/O... ... fd(%d)", node->fd);
206
207 return ret;
208}
209
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900210int cam_int_streamoff(node_info_t *node)
211{
212 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
213 int ret;
214
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700215 if (!node->streamOn)
216 return 0;
217
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900218 ALOGV("Off streaming I/O... fd(%d)", node->fd);
219 ret = exynos_v4l2_streamoff(node->fd, type);
220
221 if (ret < 0)
222 ALOGE("%s: VIDIOC_STREAMOFF failed (%d)",__FUNCTION__, ret);
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700223 else
224 node->streamOn = false;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900225
226 return ret;
227}
228
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900229int isp_int_streamoff(node_info_t *node)
230{
231 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
232 int ret;
233
234 ALOGV("Off streaming I/O... fd(%d)", node->fd);
235 ret = exynos_v4l2_streamoff(node->fd, type);
236
237 if (ret < 0)
238 ALOGE("%s: VIDIOC_STREAMOFF failed (%d)",__FUNCTION__, ret);
239
240 return ret;
241}
242
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700243int cam_int_dqbuf(node_info_t *node)
244{
245 struct v4l2_buffer v4l2_buf;
246 struct v4l2_plane planes[VIDEO_MAX_PLANES];
247 int ret;
248
249 v4l2_buf.type = node->type;
250 v4l2_buf.memory = node->memory;
251 v4l2_buf.m.planes = planes;
252 v4l2_buf.length = node->planes;
253
254 ret = exynos_v4l2_dqbuf(node->fd, &v4l2_buf);
255 if (ret < 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900256 ALOGE("%s: VIDIOC_DQBUF failed (%d)",__FUNCTION__, ret);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700257
258 return v4l2_buf.index;
259}
260
261int cam_int_s_input(node_info_t *node, int index)
262{
263 int ret;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900264
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700265 ret = exynos_v4l2_s_input(node->fd, index);
266 if (ret < 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900267 ALOGE("%s: VIDIOC_S_INPUT failed (%d)",__FUNCTION__, ret);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700268
269 return ret;
270}
271
272
273gralloc_module_t const* ExynosCameraHWInterface2::m_grallocHal;
274
275RequestManager::RequestManager(SignalDrivenThread* main_thread):
276 m_numOfEntries(0),
277 m_entryInsertionIndex(0),
278 m_entryProcessingIndex(0),
279 m_entryFrameOutputIndex(0)
280{
281 m_metadataConverter = new MetadataConverter;
282 m_mainThread = main_thread;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900283 for (int i=0 ; i<NUM_MAX_REQUEST_MGR_ENTRY; i++) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900284 memset(&(entries[i]), 0x00, sizeof(request_manager_entry_t));
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700285 entries[i].internal_shot.shot.ctl.request.frameCount = -1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900286 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -0700287 m_sensorPipelineSkipCnt = 8;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700288 return;
289}
290
291RequestManager::~RequestManager()
292{
293 return;
294}
295
296int RequestManager::GetNumEntries()
297{
298 return m_numOfEntries;
299}
300
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900301void RequestManager::SetDefaultParameters(int cropX)
302{
303 m_cropX = cropX;
304}
305
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700306bool RequestManager::IsRequestQueueFull()
307{
308 Mutex::Autolock lock(m_requestMutex);
309 if (m_numOfEntries>=NUM_MAX_REQUEST_MGR_ENTRY)
310 return true;
311 else
312 return false;
313}
314
315void RequestManager::RegisterRequest(camera_metadata_t * new_request)
316{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900317 ALOGV("DEBUG(%s):", __FUNCTION__);
318
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700319 Mutex::Autolock lock(m_requestMutex);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900320
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700321 request_manager_entry * newEntry = NULL;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900322 int newInsertionIndex = GetNextIndex(m_entryInsertionIndex);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900323 ALOGV("DEBUG(%s): got lock, new insertIndex(%d), cnt before reg(%d)", __FUNCTION__,newInsertionIndex,m_numOfEntries );
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700324
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900325
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700326 newEntry = &(entries[newInsertionIndex]);
327
328 if (newEntry->status!=EMPTY) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900329 ALOGV("DEBUG(%s): Circular buffer abnormal ", __FUNCTION__);
330 return;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700331 }
332 newEntry->status = REGISTERED;
333 newEntry->original_request = new_request;
334 // TODO : allocate internal_request dynamically
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900335 m_metadataConverter->ToInternalShot(new_request, &(newEntry->internal_shot));
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700336 newEntry->output_stream_count = newEntry->internal_shot.shot.ctl.request.id; // temp
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700337
338 m_numOfEntries++;
339 m_entryInsertionIndex = newInsertionIndex;
340
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900341
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700342 ALOGV("## RegisterReq DONE num(%d), insert(%d), processing(%d), frame(%d), (frameCnt(%d))",
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700343 m_numOfEntries,m_entryInsertionIndex,m_entryProcessingIndex, m_entryFrameOutputIndex, newEntry->internal_shot.shot.ctl.request.frameCount);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700344}
345
346void RequestManager::DeregisterRequest(camera_metadata_t ** deregistered_request)
347{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900348 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700349 Mutex::Autolock lock(m_requestMutex);
350
351 request_manager_entry * currentEntry = &(entries[m_entryFrameOutputIndex]);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900352
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700353 if (currentEntry->status != CAPTURED) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900354 ALOGD("DBG(%s): Circular buffer abnormal. processing(%d), frame(%d), status(%d) ", __FUNCTION__
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700355 , m_entryProcessingIndex, m_entryFrameOutputIndex,(int)(currentEntry->status));
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900356 return;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700357 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900358 if (deregistered_request) *deregistered_request = currentEntry->original_request;
359
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700360 currentEntry->status = EMPTY;
361 currentEntry->original_request = NULL;
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700362 memset(&(currentEntry->internal_shot), 0, sizeof(struct camera2_shot_ext));
363 currentEntry->internal_shot.shot.ctl.request.frameCount = -1;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700364 currentEntry->output_stream_count = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900365 currentEntry->dynamic_meta_vaild = false;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700366 m_numOfEntries--;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900367 // Dump();
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700368 ALOGV("## DeRegistReq DONE num(%d), insert(%d), processing(%d), frame(%d)",
369 m_numOfEntries,m_entryInsertionIndex,m_entryProcessingIndex, m_entryFrameOutputIndex);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900370
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700371 return;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700372}
373
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900374bool RequestManager::PrepareFrame(size_t* num_entries, size_t* frame_size,
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700375 camera_metadata_t ** prepared_frame)
376{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900377 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700378 Mutex::Autolock lock(m_requestMutex);
379 status_t res = NO_ERROR;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900380 int tempFrameOutputIndex = GetNextIndex(m_entryFrameOutputIndex);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900381 request_manager_entry * currentEntry = &(entries[tempFrameOutputIndex]);
382 ALOGV("DEBUG(%s): processing(%d), frameOut(%d), insert(%d) recentlycompleted(%d)", __FUNCTION__,
383 m_entryProcessingIndex, m_entryFrameOutputIndex, m_entryInsertionIndex, m_completedIndex);
384
385 if (m_completedIndex != tempFrameOutputIndex) {
386 ALOGV("DEBUG(%s): frame left behind : completed(%d), preparing(%d)", __FUNCTION__, m_completedIndex,tempFrameOutputIndex);
387
388 request_manager_entry * currentEntry2 = &(entries[tempFrameOutputIndex]);
389 currentEntry2->status = EMPTY;
390 currentEntry2->original_request = NULL;
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700391 memset(&(currentEntry2->internal_shot), 0, sizeof(struct camera2_shot_ext));
392 currentEntry2->internal_shot.shot.ctl.request.frameCount = -1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900393 currentEntry2->output_stream_count = 0;
394 currentEntry2->dynamic_meta_vaild = false;
395 m_numOfEntries--;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900396 // Dump();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900397 tempFrameOutputIndex = m_completedIndex;
398 currentEntry = &(entries[tempFrameOutputIndex]);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700399 }
400
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900401 if (currentEntry->output_stream_count!=0) {
402 ALOGD("DBG(%s): Circular buffer has remaining output : stream_count(%d)", __FUNCTION__, currentEntry->output_stream_count);
403 return false;
404 }
405
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700406 if (currentEntry->status != CAPTURED) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900407 ALOGD("DBG(%s): Circular buffer abnormal status(%d)", __FUNCTION__, (int)(currentEntry->status));
408
409 return false;
410 }
411 m_entryFrameOutputIndex = tempFrameOutputIndex;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700412 m_tempFrameMetadata = place_camera_metadata(m_tempFrameMetadataBuf, 2000, 10, 500); //estimated
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900413 res = m_metadataConverter->ToDynamicMetadata(&(currentEntry->internal_shot),
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700414 m_tempFrameMetadata);
415 if (res!=NO_ERROR) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900416 ALOGE("ERROR(%s): ToDynamicMetadata (%d) ", __FUNCTION__, res);
417 return false;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700418 }
419 *num_entries = get_camera_metadata_entry_count(m_tempFrameMetadata);
420 *frame_size = get_camera_metadata_size(m_tempFrameMetadata);
421 *prepared_frame = m_tempFrameMetadata;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900422 ALOGV("## PrepareFrame DONE: frameOut(%d) frameCnt-req(%d)", m_entryFrameOutputIndex,
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700423 currentEntry->internal_shot.shot.ctl.request.frameCount);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900424 // Dump();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900425 return true;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700426}
427
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900428int RequestManager::MarkProcessingRequest(ExynosBuffer* buf)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700429{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900430 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700431 Mutex::Autolock lock(m_requestMutex);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900432 struct camera2_shot_ext * shot_ext;
433 int targetStreamIndex = 0;
434
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900435 if (m_numOfEntries == 0) {
436 ALOGV("DEBUG(%s): Request Manager Empty ", __FUNCTION__);
437 return -1;
438 }
439
440 if ((m_entryProcessingIndex == m_entryInsertionIndex)
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700441 && (entries[m_entryProcessingIndex].status == REQUESTED || entries[m_entryProcessingIndex].status == CAPTURED)) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900442 ALOGV("## MarkProcReq skipping(request underrun) - num(%d), insert(%d), processing(%d), frame(%d)",
443 m_numOfEntries,m_entryInsertionIndex,m_entryProcessingIndex, m_entryFrameOutputIndex);
444 return -1;
445 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700446
447 request_manager_entry * newEntry = NULL;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900448 int newProcessingIndex = GetNextIndex(m_entryProcessingIndex);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700449
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700450 newEntry = &(entries[newProcessingIndex]);
451
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700452 if (newEntry->status != REGISTERED) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900453 ALOGV("DEBUG(%s): Circular buffer abnormal ", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900454 return -1;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700455 }
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700456 newEntry->status = REQUESTED;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900457 // TODO : replace the codes below with a single memcpy of pre-converted 'shot'
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700458
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900459 shot_ext = (struct camera2_shot_ext *)(buf->virt.extP[1]);
460 memset(shot_ext, 0x00, sizeof(struct camera2_shot_ext));
461
462 shot_ext->request_sensor = 1;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900463 shot_ext->dis_bypass = 1;
464 shot_ext->dnr_bypass = 1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900465 for (int i = 0; i < newEntry->output_stream_count; i++) {
466 // TODO : match with actual stream index;
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700467 targetStreamIndex = newEntry->internal_shot.shot.ctl.request.outputStreams[i];
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900468
469 if (targetStreamIndex==0) {
470 ALOGV("DEBUG(%s): outputstreams(%d) is for scalerP", __FUNCTION__, i);
471 shot_ext->request_scp = 1;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900472 shot_ext->shot.ctl.request.outputStreams[0] = 1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900473 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900474 else if (targetStreamIndex == 1) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900475 ALOGV("DEBUG(%s): outputstreams(%d) is for scalerC", __FUNCTION__, i);
476 shot_ext->request_scc = 1;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900477 shot_ext->shot.ctl.request.outputStreams[1] = 1;
478 }
479 else if (targetStreamIndex == 2) {
480 ALOGV("DEBUG(%s): outputstreams(%d) is for scalerP (record)", __FUNCTION__, i);
481 shot_ext->request_scp = 1;
482 shot_ext->shot.ctl.request.outputStreams[2] = 1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900483 }
484 else {
485 ALOGV("DEBUG(%s): outputstreams(%d) has abnormal value(%d)", __FUNCTION__, i, targetStreamIndex);
486 }
487 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900488 shot_ext->shot.ctl.request.metadataMode = METADATA_MODE_FULL;
489 shot_ext->shot.magicNumber = 0x23456789;
490 shot_ext->shot.ctl.sensor.exposureTime = 0;
491 shot_ext->shot.ctl.sensor.frameDuration = 33*1000*1000;
492 shot_ext->shot.ctl.sensor.sensitivity = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900493
494 shot_ext->shot.ctl.scaler.cropRegion[0] = 0;
495 shot_ext->shot.ctl.scaler.cropRegion[1] = 0;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900496 shot_ext->shot.ctl.scaler.cropRegion[2] = m_cropX;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900497
498 m_entryProcessingIndex = newProcessingIndex;
499
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900500 // Dump();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900501 ALOGV("## MarkProcReq DONE totalentry(%d), insert(%d), processing(%d), frame(%d) frameCnt(%d)",
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700502 m_numOfEntries,m_entryInsertionIndex,m_entryProcessingIndex, m_entryFrameOutputIndex, newEntry->internal_shot.shot.ctl.request.frameCount);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900503
504 return m_entryProcessingIndex;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700505}
506
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900507void RequestManager::NotifyStreamOutput(int frameCnt, int stream_id)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700508{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900509 int index;
510
511 ALOGV("DEBUG(%s): frameCnt(%d), stream_id(%d)", __FUNCTION__, frameCnt, stream_id);
512
513 index = FindEntryIndexByFrameCnt(frameCnt);
514 if (index == -1) {
515 ALOGE("ERR(%s): Cannot find entry for frameCnt(%d)", __FUNCTION__, frameCnt);
516 return;
517 }
518 ALOGV("DEBUG(%s): frameCnt(%d), stream_id(%d) last cnt (%d)", __FUNCTION__, frameCnt, stream_id, entries[index].output_stream_count);
519
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700520 entries[index].output_stream_count--; //TODO : match stream id also
521 CheckCompleted(index);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700522 return;
523}
524
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900525void RequestManager::CheckCompleted(int index)
526{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900527 ALOGV("DEBUG(%s): reqIndex(%d) current Count(%d)", __FUNCTION__, index, entries[index].output_stream_count);
Sungjoong Kangb5237e62012-07-27 07:39:05 -0700528 if (entries[index].output_stream_count == 0 && entries[index].dynamic_meta_vaild) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900529 ALOGV("DEBUG(%s): index[%d] completed and sending SIGNAL_MAIN_STREAM_OUTPUT_DONE", __FUNCTION__, index);
Sungjoong Kangb5237e62012-07-27 07:39:05 -0700530 // Dump();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900531 m_completedIndex = index;
532 m_mainThread->SetSignal(SIGNAL_MAIN_STREAM_OUTPUT_DONE);
533 }
534 return;
535}
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900536
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900537void RequestManager::ApplyDynamicMetadata(struct camera2_shot_ext *shot_ext, int frameCnt)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900538{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900539 int index;
540
541 ALOGV("DEBUG(%s): frameCnt(%d)", __FUNCTION__, frameCnt);
542
543 index = FindEntryIndexByFrameCnt(frameCnt);
544 if (index == -1) {
545 ALOGE("ERR(%s): Cannot find entry for frameCnt(%d)", __FUNCTION__, frameCnt);
546 return;
547 }
548
549 request_manager_entry * newEntry = &(entries[index]);
550
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700551 newEntry->dynamic_meta_vaild = true;
552 // TODO : move some code of PrepareFrame here
553 CheckCompleted(index);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900554}
555
556void RequestManager::DumpInfoWithIndex(int index)
557{
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700558 struct camera2_shot_ext * currMetadata = &(entries[index].internal_shot);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900559
560 ALOGV("#### frameCount(%d) exposureTime(%lld) ISO(%d)",
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700561 currMetadata->shot.ctl.request.frameCount,
562 currMetadata->shot.ctl.sensor.exposureTime,
563 currMetadata->shot.ctl.sensor.sensitivity);
564 if (currMetadata->shot.ctl.request.id==0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900565 ALOGV("#### No output stream selected");
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700566 else if (currMetadata->shot.ctl.request.id==1)
567 ALOGV("#### OutputStreamId : %d", currMetadata->shot.ctl.request.outputStreams[0]);
568 else if (currMetadata->shot.ctl.request.id==2)
569 ALOGV("#### OutputStreamId : %d, %d", currMetadata->shot.ctl.request.outputStreams[0],
570 currMetadata->shot.ctl.request.outputStreams[1]);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900571 else
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700572 ALOGV("#### OutputStream num (%d) abnormal ", currMetadata->shot.ctl.request.id);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900573}
574
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900575void RequestManager::UpdateOutputStreamInfo(struct camera2_shot_ext *shot_ext, int frameCnt)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900576{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900577 int index, targetStreamIndex;
578
579 ALOGV("DEBUG(%s): updating info with frameCnt(%d)", __FUNCTION__, frameCnt);
580 if (frameCnt < 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900581 return;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900582
583 index = FindEntryIndexByFrameCnt(frameCnt);
584 if (index == -1) {
585 ALOGE("ERR(%s): Cannot find entry for frameCnt(%d)", __FUNCTION__, frameCnt);
586 return;
587 }
588
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900589 request_manager_entry * newEntry = &(entries[index]);
590 shot_ext->request_sensor = 1;
591 shot_ext->request_scc = 0;
592 shot_ext->request_scp = 0;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900593 shot_ext->shot.ctl.request.outputStreams[0] = 0;
594 shot_ext->shot.ctl.request.outputStreams[1] = 0;
595 shot_ext->shot.ctl.request.outputStreams[2] = 0;
596
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900597 for (int i = 0; i < newEntry->output_stream_count; i++) {
598 // TODO : match with actual stream index;
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700599 targetStreamIndex = newEntry->internal_shot.shot.ctl.request.outputStreams[i];
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900600
601 if (targetStreamIndex==0) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900602 ALOGV("DEBUG(%s): outputstreams item[%d] is for scalerP", __FUNCTION__, i);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900603 shot_ext->request_scp = 1;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900604 shot_ext->shot.ctl.request.outputStreams[0] = 1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900605 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900606 else if (targetStreamIndex == 1) {
607 ALOGV("DEBUG(%s): outputstreams item[%d] is for scalerC", __FUNCTION__, i);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900608 shot_ext->request_scc = 1;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900609 shot_ext->shot.ctl.request.outputStreams[1] = 1;
610 }
611 else if (targetStreamIndex == 2) {
612 ALOGV("DEBUG(%s): outputstreams item[%d] is for scalerP (record)", __FUNCTION__, i);
613 shot_ext->request_scp = 1;
614 shot_ext->shot.ctl.request.outputStreams[2] = 1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900615 }
616 else {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900617 ALOGV("DEBUG(%s): outputstreams item[%d] has abnormal value(%d)", __FUNCTION__, i, targetStreamIndex);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900618 }
619 }
620}
621
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900622int RequestManager::FindEntryIndexByFrameCnt(int frameCnt)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900623{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900624 for (int i = 0 ; i < NUM_MAX_REQUEST_MGR_ENTRY ; i++) {
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700625 if (entries[i].internal_shot.shot.ctl.request.frameCount == frameCnt)
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900626 return i;
627 }
628 return -1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900629}
630
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900631void RequestManager::RegisterTimestamp(int frameCnt, nsecs_t * frameTime)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900632{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900633 int index = FindEntryIndexByFrameCnt(frameCnt);
634 if (index == -1) {
635 ALOGE("ERR(%s): Cannot find entry for frameCnt(%d)", __FUNCTION__, frameCnt);
636 return;
637 }
638
639 request_manager_entry * currentEntry = &(entries[index]);
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700640 currentEntry->internal_shot.shot.dm.sensor.timeStamp = *((uint64_t*)frameTime);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900641 ALOGV("DEBUG(%s): applied timestamp for reqIndex(%d) frameCnt(%d) (%lld)", __FUNCTION__,
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700642 index, frameCnt, currentEntry->internal_shot.shot.dm.sensor.timeStamp);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900643}
644
645uint64_t RequestManager::GetTimestamp(int frameCnt)
646{
647 int index = FindEntryIndexByFrameCnt(frameCnt);
648 if (index == -1) {
649 ALOGE("ERR(%s): Cannot find entry for frameCnt(%d)", __FUNCTION__, frameCnt);
650 return 0;
651 }
652
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900653 request_manager_entry * currentEntry = &(entries[index]);
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700654 uint64_t frameTime = currentEntry->internal_shot.shot.dm.sensor.timeStamp;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900655 ALOGV("DEBUG(%s): Returning timestamp for reqIndex(%d) (%lld)", __FUNCTION__, index, frameTime);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900656 return frameTime;
657}
658
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900659int RequestManager::FindFrameCnt(struct camera2_shot_ext * shot_ext)
660{
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700661 int tempIndex, i;
Sungjoong Kangb5237e62012-07-27 07:39:05 -0700662 if (m_sensorPipelineSkipCnt > 0) {
663 m_sensorPipelineSkipCnt--;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900664 return -1;
665 }
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700666 if (m_numOfEntries == 0) {
667 ALOGD("(%s): No Entry found", __FUNCTION__);
668 return -1;
669 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900670 tempIndex = GetNextIndex(m_entryFrameOutputIndex);
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700671 for (i = 0 ; i < NUM_MAX_REQUEST_MGR_ENTRY ; i++) {
672 if (entries[tempIndex].status == REQUESTED) {
673 entries[tempIndex].status = CAPTURED;
674 return entries[tempIndex].internal_shot.shot.ctl.request.frameCount;
675 }
676 else if (entries[tempIndex].status == CAPTURED) {
677 tempIndex = GetNextIndex(tempIndex);
678 continue;
679 }
680 else {
681 ALOGE("(%s): enry state abnormal status(%d)", __FUNCTION__, entries[tempIndex].status);
682 Dump();
683 return -1;
684 }
685 }
686 return -1;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900687}
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900688
Sungjoong Kangb5237e62012-07-27 07:39:05 -0700689void RequestManager::SetInitialSkip(int count)
690{
691 ALOGV("(%s): Pipeline Restarting. setting cnt(%d) - current(%d)", __FUNCTION__, count, m_sensorPipelineSkipCnt);
692 if (count > m_sensorPipelineSkipCnt)
693 m_sensorPipelineSkipCnt = count;
694}
695
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900696void RequestManager::Dump(void)
697{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900698 int i = 0;
699 request_manager_entry * currentEntry;
700 ALOGV("## Dump totalentry(%d), insert(%d), processing(%d), frame(%d)",
701 m_numOfEntries,m_entryInsertionIndex,m_entryProcessingIndex, m_entryFrameOutputIndex);
702
703 for (i = 0 ; i < NUM_MAX_REQUEST_MGR_ENTRY ; i++) {
704 currentEntry = &(entries[i]);
705 ALOGV("[%2d] status[%d] frameCnt[%3d] numOutput[%d]", i,
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700706 currentEntry->status, currentEntry->internal_shot.shot.ctl.request.frameCount,
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900707 currentEntry->output_stream_count);
708 }
709}
710
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900711int RequestManager::GetNextIndex(int index)
712{
713 index++;
714 if (index >= NUM_MAX_REQUEST_MGR_ENTRY)
715 index = 0;
716
717 return index;
718}
719
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -0700720ExynosCameraHWInterface2::ExynosCameraHWInterface2(int cameraId, camera2_device_t *dev, ExynosCamera2 * camera):
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700721 m_requestQueueOps(NULL),
722 m_frameQueueOps(NULL),
723 m_callbackCookie(NULL),
724 m_numOfRemainingReqInSvc(0),
725 m_isRequestQueuePending(false),
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900726 m_isRequestQueueNull(true),
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700727 m_isSensorThreadOn(false),
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900728 m_isSensorStarted(false),
729 m_ionCameraClient(0),
730 m_initFlag1(false),
731 m_initFlag2(false),
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900732 m_scp_flushing(false),
733 m_closing(false),
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900734 m_recordingEnabled(false),
735 m_needsRecordBufferInit(false),
736 lastFrameCnt(-1),
737 m_scp_closing(false),
738 m_scp_closed(false),
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900739 m_halDevice(dev),
Sungjoong Kangbe494d12012-08-04 15:36:56 -0700740 m_cameraId(cameraId)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700741{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900742 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700743 int ret = 0;
744
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900745 m_exynosPictureCSC = NULL;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900746 m_exynosVideoCSC = NULL;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900747
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700748 if (!m_grallocHal) {
749 ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&m_grallocHal);
750 if (ret)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900751 ALOGE("ERR(%s):Fail on loading gralloc HAL", __FUNCTION__);
752 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700753
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -0700754 m_camera2 = camera;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700755 m_ionCameraClient = createIonClient(m_ionCameraClient);
756 if(m_ionCameraClient == 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900757 ALOGE("ERR(%s):Fail on ion_client_create", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700758
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900759
760 m_BayerManager = new BayerBufManager();
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700761 m_mainThread = new MainThread(this);
762 m_sensorThread = new SensorThread(this);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900763 m_ispThread = new IspThread(this);
764 m_mainThread->Start("MainThread", PRIORITY_DEFAULT, 0);
765 ALOGV("DEBUG(%s): created sensorthread ################", __FUNCTION__);
766 usleep(1600000);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700767
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900768 m_requestManager = new RequestManager((SignalDrivenThread*)(m_mainThread.get()));
769 CSC_METHOD cscMethod = CSC_METHOD_HW;
770 m_exynosPictureCSC = csc_init(cscMethod);
771 if (m_exynosPictureCSC == NULL)
772 ALOGE("ERR(%s): csc_init() fail", __FUNCTION__);
773 csc_set_hw_property(m_exynosPictureCSC, CSC_HW_PROPERTY_FIXED_NODE, PICTURE_GSC_NODE_NUM);
774
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900775 m_exynosVideoCSC = csc_init(cscMethod);
776 if (m_exynosVideoCSC == NULL)
777 ALOGE("ERR(%s): csc_init() fail", __FUNCTION__);
778 csc_set_hw_property(m_exynosVideoCSC, CSC_HW_PROPERTY_FIXED_NODE, PREVIEW_GSC_NODE_NUM);
779
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900780 ALOGV("DEBUG(%s): END", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700781}
782
783ExynosCameraHWInterface2::~ExynosCameraHWInterface2()
784{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900785 ALOGD("%s: ENTER", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700786 this->release();
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900787 ALOGD("%s: EXIT", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700788}
789
790void ExynosCameraHWInterface2::release()
791{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900792 int i, res;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900793 ALOGD("%s: ENTER", __func__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900794 m_closing = true;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900795
796 while (!m_scp_closed)
797 usleep(1000);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900798 if (m_ispThread != NULL) {
799 m_ispThread->release();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900800 }
801
802 if (m_sensorThread != NULL) {
803 m_sensorThread->release();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900804 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700805
806 if (m_mainThread != NULL) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900807 m_mainThread->release();
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700808 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700809
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900810 if (m_streamThreads[0] != NULL) {
811 m_streamThreads[0]->release();
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900812 m_streamThreads[0]->SetSignal(SIGNAL_THREAD_TERMINATE);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700813 }
814
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900815 if (m_streamThreads[1] != NULL) {
816 m_streamThreads[1]->release();
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900817 m_streamThreads[1]->SetSignal(SIGNAL_THREAD_TERMINATE);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900818 }
819
820
821 if (m_exynosPictureCSC)
822 csc_deinit(m_exynosPictureCSC);
823 m_exynosPictureCSC = NULL;
824
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900825 if (m_exynosVideoCSC)
826 csc_deinit(m_exynosVideoCSC);
827 m_exynosVideoCSC = NULL;
828
829 if (m_ispThread != NULL) {
830 while (!m_ispThread->IsTerminated())
831 usleep(1000);
832 m_ispThread = NULL;
833 }
834
835 if (m_sensorThread != NULL) {
836 while (!m_sensorThread->IsTerminated())
837 usleep(1000);
838 m_sensorThread = NULL;
839 }
840
841 if (m_mainThread != NULL) {
842 while (!m_mainThread->IsTerminated())
843 usleep(1000);
844 m_mainThread = NULL;
845 }
846
847 if (m_streamThreads[0] != NULL) {
848 while (!m_streamThreads[0]->IsTerminated())
849 usleep(1000);
850 m_streamThreads[0] = NULL;
851 }
852
853 if (m_streamThreads[1] != NULL) {
854 while (!m_streamThreads[1]->IsTerminated())
855 usleep(1000);
856 m_streamThreads[1] = NULL;
857 }
858
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700859 for(i = 0; i < m_camera_info.sensor.buffers; i++)
860 freeCameraMemory(&m_camera_info.sensor.buffer[i], m_camera_info.sensor.planes);
861
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700862 for(i = 0; i < m_camera_info.capture.buffers; i++)
863 freeCameraMemory(&m_camera_info.capture.buffer[i], m_camera_info.capture.planes);
864
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900865 ALOGV("DEBUG(%s): calling exynos_v4l2_close - sensor", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900866 res = exynos_v4l2_close(m_camera_info.sensor.fd);
867 if (res != NO_ERROR ) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900868 ALOGE("ERR(%s): exynos_v4l2_close failed(%d)",__FUNCTION__ , res);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900869 }
870
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900871 ALOGV("DEBUG(%s): calling exynos_v4l2_close - isp", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900872 res = exynos_v4l2_close(m_camera_info.isp.fd);
873 if (res != NO_ERROR ) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900874 ALOGE("ERR(%s): exynos_v4l2_close failed(%d)",__FUNCTION__ , res);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900875 }
876
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900877 ALOGV("DEBUG(%s): calling exynos_v4l2_close - capture", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900878 res = exynos_v4l2_close(m_camera_info.capture.fd);
879 if (res != NO_ERROR ) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900880 ALOGE("ERR(%s): exynos_v4l2_close failed(%d)",__FUNCTION__ , res);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900881 }
882
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900883 ALOGV("DEBUG(%s): calling exynos_v4l2_close - scp", __FUNCTION__);
884 res = exynos_v4l2_close(m_fd_scp);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900885 if (res != NO_ERROR ) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900886 ALOGE("ERR(%s): exynos_v4l2_close failed(%d)",__FUNCTION__ , res);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900887 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900888 ALOGV("DEBUG(%s): calling deleteIonClient", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700889 deleteIonClient(m_ionCameraClient);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900890
891 ALOGD("%s: EXIT", __func__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900892}
893
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700894int ExynosCameraHWInterface2::getCameraId() const
895{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900896 return m_cameraId;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700897}
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700898
899int ExynosCameraHWInterface2::setRequestQueueSrcOps(const camera2_request_queue_src_ops_t *request_src_ops)
900{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900901 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700902 if ((NULL != request_src_ops) && (NULL != request_src_ops->dequeue_request)
903 && (NULL != request_src_ops->free_request) && (NULL != request_src_ops->request_count)) {
904 m_requestQueueOps = (camera2_request_queue_src_ops_t*)request_src_ops;
905 return 0;
906 }
907 else {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900908 ALOGE("DEBUG(%s):setRequestQueueSrcOps : NULL arguments", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700909 return 1;
910 }
911}
912
913int ExynosCameraHWInterface2::notifyRequestQueueNotEmpty()
914{
Sungjoong Kangb5237e62012-07-27 07:39:05 -0700915 ALOGV("DEBUG(%s):setting [SIGNAL_MAIN_REQ_Q_NOT_EMPTY] current(%d)", __FUNCTION__, m_requestManager->GetNumEntries());
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700916 if ((NULL==m_frameQueueOps)|| (NULL==m_requestQueueOps)) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900917 ALOGE("DEBUG(%s):queue ops NULL. ignoring request", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700918 return 0;
919 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900920 m_isRequestQueueNull = false;
Sungjoong Kangb5237e62012-07-27 07:39:05 -0700921 if (m_requestManager->GetNumEntries() == 0)
922 m_requestManager->SetInitialSkip(5);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700923 m_mainThread->SetSignal(SIGNAL_MAIN_REQ_Q_NOT_EMPTY);
924 return 0;
925}
926
927int ExynosCameraHWInterface2::setFrameQueueDstOps(const camera2_frame_queue_dst_ops_t *frame_dst_ops)
928{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900929 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700930 if ((NULL != frame_dst_ops) && (NULL != frame_dst_ops->dequeue_frame)
931 && (NULL != frame_dst_ops->cancel_frame) && (NULL !=frame_dst_ops->enqueue_frame)) {
932 m_frameQueueOps = (camera2_frame_queue_dst_ops_t *)frame_dst_ops;
933 return 0;
934 }
935 else {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900936 ALOGE("DEBUG(%s):setFrameQueueDstOps : NULL arguments", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700937 return 1;
938 }
939}
940
941int ExynosCameraHWInterface2::getInProgressCount()
942{
943 int inProgressCount = m_requestManager->GetNumEntries();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900944 ALOGV("DEBUG(%s): # of dequeued req (%d)", __FUNCTION__, inProgressCount);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700945 return inProgressCount;
946}
947
948int ExynosCameraHWInterface2::flushCapturesInProgress()
949{
950 return 0;
951}
952
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700953int ExynosCameraHWInterface2::constructDefaultRequest(int request_template, camera_metadata_t **request)
954{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900955 ALOGV("DEBUG(%s): making template (%d) ", __FUNCTION__, request_template);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700956
957 if (request == NULL) return BAD_VALUE;
958 if (request_template < 0 || request_template >= CAMERA2_TEMPLATE_COUNT) {
959 return BAD_VALUE;
960 }
961 status_t res;
962 // Pass 1, calculate size and allocate
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -0700963 res = m_camera2->constructDefaultRequest(request_template,
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700964 request,
965 true);
966 if (res != OK) {
967 return res;
968 }
969 // Pass 2, build request
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -0700970 res = m_camera2->constructDefaultRequest(request_template,
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700971 request,
972 false);
973 if (res != OK) {
974 ALOGE("Unable to populate new request for template %d",
975 request_template);
976 }
977
978 return res;
979}
980
981int ExynosCameraHWInterface2::allocateStream(uint32_t width, uint32_t height, int format, const camera2_stream_ops_t *stream_ops,
982 uint32_t *stream_id, uint32_t *format_actual, uint32_t *usage, uint32_t *max_buffers)
983{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900984 ALOGD("DEBUG(%s): allocate stream width(%d) height(%d) format(%x)", __FUNCTION__, width, height, format);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700985 char node_name[30];
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900986 int fd = 0, allocCase = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900987 StreamThread *AllocatedStream;
988 stream_parameters_t newParameters;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700989
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -0700990 if (format == CAMERA2_HAL_PIXEL_FORMAT_OPAQUE &&
991 m_camera2->isSupportedResolution(width, height)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900992 if (!(m_streamThreads[0].get())) {
993 ALOGV("DEBUG(%s): stream 0 not exist", __FUNCTION__);
994 allocCase = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700995 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900996 else {
Alex Ray6bbb5932012-07-27 17:19:48 -0700997 if ((m_streamThreads[0].get())->m_activated == true) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900998 ALOGV("DEBUG(%s): stream 0 exists and activated.", __FUNCTION__);
999 allocCase = 1;
1000 }
1001 else {
1002 ALOGV("DEBUG(%s): stream 0 exists and deactivated.", __FUNCTION__);
1003 allocCase = 2;
1004 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001005 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001006 if (allocCase == 0 || allocCase == 2) {
1007 *stream_id = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001008
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001009 if (allocCase == 0) {
1010 m_streamThreads[0] = new StreamThread(this, *stream_id);
1011
1012
1013 memset(&node_name, 0x00, sizeof(char[30]));
1014 sprintf(node_name, "%s%d", NODE_PREFIX, 44);
1015 fd = exynos_v4l2_open(node_name, O_RDWR, 0);
1016 if (fd < 0) {
1017 ALOGE("DEBUG(%s): failed to open preview video node (%s) fd (%d)", __FUNCTION__,node_name, fd);
1018 }
1019 else {
1020 ALOGV("DEBUG(%s): preview video node opened(%s) fd (%d)", __FUNCTION__,node_name, fd);
1021 }
1022 m_fd_scp = fd;
1023 }
1024 AllocatedStream = (StreamThread*)(m_streamThreads[0].get());
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001025 m_scp_flushing = false;
1026 m_scp_closing = false;
1027 m_scp_closed = false;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001028 usleep(100000); // TODO : guarantee the codes below will be run after readyToRunInternal()
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001029
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001030 *format_actual = HAL_PIXEL_FORMAT_YV12;
Alex Ray6bbb5932012-07-27 17:19:48 -07001031 *usage = GRALLOC_USAGE_SW_WRITE_OFTEN;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001032 *max_buffers = 8;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001033
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001034 newParameters.streamType = 0;
1035 newParameters.outputWidth = width;
1036 newParameters.outputHeight = height;
1037 newParameters.nodeWidth = width;
1038 newParameters.nodeHeight = height;
1039 newParameters.outputFormat = *format_actual;
1040 newParameters.nodeFormat = HAL_PIXEL_FORMAT_2_V4L2_PIX(*format_actual);
1041 newParameters.streamOps = stream_ops;
1042 newParameters.usage = *usage;
Sungjoong Kangbe494d12012-08-04 15:36:56 -07001043 newParameters.numHwBuffers = 8;
1044 newParameters.numOwnSvcBuffers = *max_buffers;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001045 newParameters.fd = m_fd_scp;
1046 newParameters.nodePlanes = 3;
1047 newParameters.svcPlanes = 3;
1048 newParameters.halBuftype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1049 newParameters.memory = V4L2_MEMORY_DMABUF;
1050 newParameters.ionClient = m_ionCameraClient;
Sungjoong Kangbe494d12012-08-04 15:36:56 -07001051 newParameters.numSvcBufsInHal = 0;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001052 AllocatedStream->m_index = *stream_id;
1053 AllocatedStream->setParameter(&newParameters);
1054 AllocatedStream->m_activated = true;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001055
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001056 m_scp_flushing = false;
1057 m_scp_closing = false;
1058 m_scp_closed = false;
1059 m_requestManager->SetDefaultParameters(width);
1060 m_camera_info.dummy_shot.shot.ctl.scaler.cropRegion[2] = width;
1061 return 0;
1062 }
1063 else if (allocCase == 1) {
1064 record_parameters_t recordParameters;
1065 StreamThread *parentStream;
1066 parentStream = (StreamThread*)(m_streamThreads[0].get());
1067 if (!parentStream) {
1068 return 1;
1069 // TODO
1070 }
1071 *stream_id = 2;
1072 usleep(100000); // TODO : guarantee the codes below will be run after readyToRunInternal()
1073
Sungjoong Kang804236a2012-08-05 10:36:19 -07001074 *format_actual = HAL_PIXEL_FORMAT_YCbCr_420_SP; // NV12M
Alex Ray6bbb5932012-07-27 17:19:48 -07001075 *usage = GRALLOC_USAGE_SW_WRITE_OFTEN;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001076 *max_buffers = 10;
1077
1078 recordParameters.outputWidth = width;
1079 recordParameters.outputHeight = height;
1080 recordParameters.outputFormat = *format_actual;
Sungjoong Kang804236a2012-08-05 10:36:19 -07001081 recordParameters.svcPlanes = NUM_PLANES(*format_actual);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001082 recordParameters.streamOps = stream_ops;
1083 recordParameters.usage = *usage;
Sungjoong Kangbe494d12012-08-04 15:36:56 -07001084 recordParameters.numOwnSvcBuffers = *max_buffers;
1085 recordParameters.numSvcBufsInHal = 0;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001086
1087 parentStream->setRecordingParameter(&recordParameters);
1088 m_scp_flushing = false;
1089 m_scp_closing = false;
1090 m_scp_closed = false;
1091 m_recordingEnabled = true;
1092 return 0;
1093 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001094 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001095 else if (format == HAL_PIXEL_FORMAT_BLOB
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07001096 && m_camera2->isSupportedJpegResolution(width, height)) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001097
1098 *stream_id = 1;
1099
1100 m_streamThreads[1] = new StreamThread(this, *stream_id);
1101 AllocatedStream = (StreamThread*)(m_streamThreads[1].get());
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001102
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001103 fd = m_camera_info.capture.fd;
1104 usleep(100000); // TODO : guarantee the codes below will be run after readyToRunInternal()
1105
1106 *format_actual = HAL_PIXEL_FORMAT_BLOB;
1107
1108 *usage = GRALLOC_USAGE_SW_WRITE_OFTEN;
1109 *max_buffers = 8;
1110
1111 newParameters.streamType = 1;
1112 newParameters.outputWidth = width;
1113 newParameters.outputHeight = height;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001114
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07001115 newParameters.nodeWidth = m_camera2->getSensorW();
1116 newParameters.nodeHeight = m_camera2->getSensorH();
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001117
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001118 newParameters.outputFormat = *format_actual;
1119 newParameters.nodeFormat = V4L2_PIX_FMT_YUYV;
1120 newParameters.streamOps = stream_ops;
1121 newParameters.usage = *usage;
Sungjoong Kangbe494d12012-08-04 15:36:56 -07001122 newParameters.numHwBuffers = 8;
1123 newParameters.numOwnSvcBuffers = *max_buffers;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001124 newParameters.fd = fd;
1125 newParameters.nodePlanes = 1;
1126 newParameters.svcPlanes = 1;
1127 newParameters.halBuftype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1128 newParameters.memory = V4L2_MEMORY_DMABUF;
1129 newParameters.ionClient = m_ionCameraClient;
Sungjoong Kangbe494d12012-08-04 15:36:56 -07001130 newParameters.numSvcBufsInHal = 0;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001131 AllocatedStream->m_index = *stream_id;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001132 AllocatedStream->setParameter(&newParameters);
1133 return 0;
1134 }
1135 ALOGE("DEBUG(%s): Unsupported Pixel Format", __FUNCTION__);
1136 return 1; // TODO : check proper error code
1137}
1138
1139int ExynosCameraHWInterface2::registerStreamBuffers(uint32_t stream_id,
1140 int num_buffers, buffer_handle_t *registeringBuffers)
1141{
1142 int i,j;
1143 void *virtAddr[3];
1144 uint32_t plane_index = 0;
1145 stream_parameters_t *targetStreamParms;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001146 record_parameters_t *targetRecordParms;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001147 node_info_t *currentNode;
1148
1149 struct v4l2_buffer v4l2_buf;
1150 struct v4l2_plane planes[VIDEO_MAX_PLANES];
1151
1152 ALOGV("DEBUG(%s): streamID (%d), num_buff(%d), handle(%x) ", __FUNCTION__,
1153 stream_id, num_buffers, (uint32_t)registeringBuffers);
1154
1155 if (stream_id == 0) {
1156 targetStreamParms = &(m_streamThreads[0]->m_parameters);
1157 }
1158 else if (stream_id == 1) {
1159 targetStreamParms = &(m_streamThreads[1]->m_parameters);
1160 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001161 else if (stream_id == 2) {
1162 targetRecordParms = &(m_streamThreads[0]->m_recordParameters);
1163
1164 targetRecordParms->numSvcBuffers = num_buffers;
1165
1166 for (i = 0 ; i<targetRecordParms->numSvcBuffers ; i++) {
1167 ALOGV("DEBUG(%s): registering Stream Buffers[%d] (%x) ", __FUNCTION__,
1168 i, (uint32_t)(registeringBuffers[i]));
1169 if (m_grallocHal) {
1170 if (m_grallocHal->lock(m_grallocHal, registeringBuffers[i],
1171 targetRecordParms->usage, 0, 0,
1172 targetRecordParms->outputWidth, targetRecordParms->outputHeight, virtAddr) != 0) {
1173 ALOGE("ERR(%s): could not obtain gralloc buffer", __FUNCTION__);
1174 }
1175 else {
1176 ExynosBuffer currentBuf;
1177 const private_handle_t *priv_handle = reinterpret_cast<const private_handle_t *>(registeringBuffers[i]);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001178 currentBuf.fd.extFd[0] = priv_handle->fd;
Alex Ray6bbb5932012-07-27 17:19:48 -07001179 currentBuf.fd.extFd[1] = priv_handle->fd1;
1180 currentBuf.fd.extFd[2] = priv_handle->fd2;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001181 for (plane_index=0 ; plane_index < targetRecordParms->svcPlanes ; plane_index++) {
1182 currentBuf.virt.extP[plane_index] = (char *)virtAddr[plane_index];
1183 ALOGV("DEBUG(%s): plane(%d): fd(%d) addr(%x)",
Sungjoong Kang804236a2012-08-05 10:36:19 -07001184 __FUNCTION__, plane_index, currentBuf.fd.extFd[plane_index],
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001185 (unsigned int)currentBuf.virt.extP[plane_index]);
1186 }
1187 targetRecordParms->svcBufStatus[i] = ON_SERVICE;
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001188 targetRecordParms->svcBuffers[i] = currentBuf;
1189 targetRecordParms->svcBufHandle[i] = registeringBuffers[i];
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001190 }
1191 }
1192 }
1193 m_needsRecordBufferInit = true;
1194 return 0;
1195 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001196 else {
1197 ALOGE("ERR(%s) unregisterd stream id (%d)", __FUNCTION__, stream_id);
Sungjoong Kangbe494d12012-08-04 15:36:56 -07001198 return 1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001199 }
1200
Sungjoong Kangbe494d12012-08-04 15:36:56 -07001201 if (targetStreamParms->streamType == 0) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001202 if (num_buffers < targetStreamParms->numHwBuffers) {
1203 ALOGE("ERR(%s) registering insufficient num of buffers (%d) < (%d)",
1204 __FUNCTION__, num_buffers, targetStreamParms->numHwBuffers);
Sungjoong Kangbe494d12012-08-04 15:36:56 -07001205 return 1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001206 }
1207 }
1208 ALOGV("DEBUG(%s): format(%x) width(%d), height(%d) svcPlanes(%d)",
1209 __FUNCTION__, targetStreamParms->outputFormat, targetStreamParms->outputWidth,
1210 targetStreamParms->outputHeight, targetStreamParms->svcPlanes);
1211
1212 targetStreamParms->numSvcBuffers = num_buffers;
1213 currentNode = &(targetStreamParms->node); // TO Remove
1214
1215 currentNode->fd = targetStreamParms->fd;
1216 currentNode->width = targetStreamParms->nodeWidth;
1217 currentNode->height = targetStreamParms->nodeHeight;
1218 currentNode->format = targetStreamParms->nodeFormat;
1219 currentNode->planes = targetStreamParms->nodePlanes;
1220 currentNode->buffers = targetStreamParms->numHwBuffers;
1221 currentNode->type = targetStreamParms->halBuftype;
1222 currentNode->memory = targetStreamParms->memory;
1223 currentNode->ionClient = targetStreamParms->ionClient;
1224
1225 if (targetStreamParms->streamType == 0) {
1226 cam_int_s_input(currentNode, m_camera_info.sensor_id);
1227 cam_int_s_fmt(currentNode);
1228 cam_int_reqbufs(currentNode);
1229 }
1230 else if (targetStreamParms->streamType == 1) {
1231 for(i = 0; i < currentNode->buffers; i++){
1232 memcpy(&(currentNode->buffer[i]), &(m_camera_info.capture.buffer[i]), sizeof(ExynosBuffer));
1233 }
1234 }
1235
1236 for (i = 0 ; i<targetStreamParms->numSvcBuffers ; i++) {
1237 ALOGV("DEBUG(%s): registering Stream Buffers[%d] (%x) ", __FUNCTION__,
1238 i, (uint32_t)(registeringBuffers[i]));
1239 if (m_grallocHal) {
1240 if (m_grallocHal->lock(m_grallocHal, registeringBuffers[i],
1241 targetStreamParms->usage, 0, 0,
1242 currentNode->width, currentNode->height, virtAddr) != 0) {
1243 ALOGE("ERR(%s): could not obtain gralloc buffer", __FUNCTION__);
1244 }
1245 else {
1246 v4l2_buf.m.planes = planes;
1247 v4l2_buf.type = currentNode->type;
1248 v4l2_buf.memory = currentNode->memory;
1249 v4l2_buf.index = i;
1250 v4l2_buf.length = currentNode->planes;
1251
1252 ExynosBuffer currentBuf;
1253 const private_handle_t *priv_handle = reinterpret_cast<const private_handle_t *>(registeringBuffers[i]);
1254
1255 m_getAlignedYUVSize(currentNode->format,
1256 currentNode->width, currentNode->height, &currentBuf);
Alex Ray24231222012-06-27 15:18:15 -07001257
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001258 v4l2_buf.m.planes[0].m.fd = priv_handle->fd;
Alex Ray6bbb5932012-07-27 17:19:48 -07001259 v4l2_buf.m.planes[2].m.fd = priv_handle->fd1;
1260 v4l2_buf.m.planes[1].m.fd = priv_handle->fd2;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001261 currentBuf.fd.extFd[0] = priv_handle->fd;
Alex Ray6bbb5932012-07-27 17:19:48 -07001262 currentBuf.fd.extFd[2] = priv_handle->fd1;
1263 currentBuf.fd.extFd[1] = priv_handle->fd2;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001264 ALOGV("DEBUG(%s): ion_size(%d), stride(%d), ", __FUNCTION__,priv_handle->size, priv_handle->stride);
1265
1266
Sungjoong Kangbe494d12012-08-04 15:36:56 -07001267 for (plane_index = 0 ; plane_index < v4l2_buf.length ; plane_index++) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001268 currentBuf.virt.extP[plane_index] = (char *)virtAddr[plane_index];
1269 v4l2_buf.m.planes[plane_index].length = currentBuf.size.extS[plane_index];
1270 ALOGV("DEBUG(%s): plane(%d): fd(%d) addr(%x), length(%d)",
1271 __FUNCTION__, plane_index, v4l2_buf.m.planes[plane_index].m.fd,
1272 (unsigned int)currentBuf.virt.extP[plane_index],
1273 v4l2_buf.m.planes[plane_index].length);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001274 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001275
1276 if (targetStreamParms->streamType == 0) {
1277 if (i < currentNode->buffers) {
1278 if (exynos_v4l2_qbuf(currentNode->fd, &v4l2_buf) < 0) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001279 ALOGE("ERR(%s): stream id(%d) exynos_v4l2_qbuf() fail fd(%d)",
1280 __FUNCTION__, stream_id, currentNode->fd);
1281 //return false;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001282 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001283 ALOGV("DEBUG(%s): stream id(%d) exynos_v4l2_qbuf() success fd(%d)",
1284 __FUNCTION__, stream_id, currentNode->fd);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001285 targetStreamParms->svcBufStatus[i] = REQUIRES_DQ_FROM_SVC;
1286 }
1287 else {
1288 targetStreamParms->svcBufStatus[i] = ON_SERVICE;
1289 }
1290 }
1291 else if (targetStreamParms->streamType == 1) {
1292 targetStreamParms->svcBufStatus[i] = ON_SERVICE;
1293 }
1294 targetStreamParms->svcBuffers[i] = currentBuf;
1295 targetStreamParms->svcBufHandle[i] = registeringBuffers[i];
1296 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001297 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001298 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001299 ALOGV("DEBUG(%s): calling streamon", __FUNCTION__);
1300 cam_int_streamon(&(targetStreamParms->node));
1301 ALOGV("DEBUG(%s): calling streamon END", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001302 ALOGV("DEBUG(%s): END registerStreamBuffers", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001303 return 0;
1304}
1305
1306int ExynosCameraHWInterface2::releaseStream(uint32_t stream_id)
1307{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001308 StreamThread *targetStream;
1309 ALOGV("DEBUG(%s):", __FUNCTION__);
1310
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001311 if (stream_id == 0) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001312 targetStream = (StreamThread*)(m_streamThreads[0].get());
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001313 m_scp_flushing = true;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001314 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001315 else if (stream_id == 1) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001316 targetStream = (StreamThread*)(m_streamThreads[1].get());
1317 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001318 else if (stream_id == 2 && m_recordingEnabled) {
1319 m_recordingEnabled = false;
1320 return 0;
1321 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001322 else {
1323 ALOGE("ERR:(%s): wrong stream id (%d)", __FUNCTION__, stream_id);
Sungjoong Kangbe494d12012-08-04 15:36:56 -07001324 return 1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001325 }
1326
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001327 targetStream->m_releasing = true;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001328 targetStream->release();
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001329 while (targetStream->m_releasing)
1330 usleep(2000);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001331 targetStream->m_activated = false;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001332 ALOGV("DEBUG(%s): DONE", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001333 return 0;
1334}
1335
1336int ExynosCameraHWInterface2::allocateReprocessStream(
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001337 uint32_t width, uint32_t height, uint32_t format,
1338 const camera2_stream_in_ops_t *reprocess_stream_ops,
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001339 uint32_t *stream_id, uint32_t *consumer_usage, uint32_t *max_buffers)
1340{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001341 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001342 return 0;
1343}
1344
1345int ExynosCameraHWInterface2::releaseReprocessStream(uint32_t stream_id)
1346{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001347 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001348 return 0;
1349}
1350
1351int ExynosCameraHWInterface2::triggerAction(uint32_t trigger_id, int ext1, int ext2)
1352{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001353 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001354 return 0;
1355}
1356
1357int ExynosCameraHWInterface2::setNotifyCallback(camera2_notify_callback notify_cb, void *user)
1358{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001359 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001360 m_notifyCb = notify_cb;
1361 m_callbackCookie = user;
1362 return 0;
1363}
1364
1365int ExynosCameraHWInterface2::getMetadataVendorTagOps(vendor_tag_query_ops_t **ops)
1366{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001367 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001368 return 0;
1369}
1370
1371int ExynosCameraHWInterface2::dump(int fd)
1372{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001373 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001374 return 0;
1375}
1376
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001377void ExynosCameraHWInterface2::m_getAlignedYUVSize(int colorFormat, int w, int h, ExynosBuffer *buf)
1378{
1379 switch (colorFormat) {
1380 // 1p
1381 case V4L2_PIX_FMT_RGB565 :
1382 case V4L2_PIX_FMT_YUYV :
1383 case V4L2_PIX_FMT_UYVY :
1384 case V4L2_PIX_FMT_VYUY :
1385 case V4L2_PIX_FMT_YVYU :
1386 buf->size.extS[0] = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(colorFormat), w, h);
1387 buf->size.extS[1] = 0;
1388 buf->size.extS[2] = 0;
1389 break;
1390 // 2p
1391 case V4L2_PIX_FMT_NV12 :
1392 case V4L2_PIX_FMT_NV12T :
1393 case V4L2_PIX_FMT_NV21 :
1394 buf->size.extS[0] = ALIGN(w, 16) * ALIGN(h, 16);
1395 buf->size.extS[1] = ALIGN(w/2, 16) * ALIGN(h/2, 16);
1396 buf->size.extS[2] = 0;
1397 break;
1398 case V4L2_PIX_FMT_NV12M :
1399 case V4L2_PIX_FMT_NV12MT_16X16 :
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001400 case V4L2_PIX_FMT_NV21M:
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001401 buf->size.extS[0] = ALIGN(w, 16) * ALIGN(h, 16);
1402 buf->size.extS[1] = ALIGN(buf->size.extS[0] / 2, 256);
1403 buf->size.extS[2] = 0;
1404 break;
1405 case V4L2_PIX_FMT_NV16 :
1406 case V4L2_PIX_FMT_NV61 :
1407 buf->size.extS[0] = ALIGN(w, 16) * ALIGN(h, 16);
1408 buf->size.extS[1] = ALIGN(w, 16) * ALIGN(h, 16);
1409 buf->size.extS[2] = 0;
1410 break;
1411 // 3p
1412 case V4L2_PIX_FMT_YUV420 :
1413 case V4L2_PIX_FMT_YVU420 :
1414 buf->size.extS[0] = (w * h);
1415 buf->size.extS[1] = (w * h) >> 2;
1416 buf->size.extS[2] = (w * h) >> 2;
1417 break;
1418 case V4L2_PIX_FMT_YUV420M:
1419 case V4L2_PIX_FMT_YVU420M :
1420 case V4L2_PIX_FMT_YUV422P :
1421 buf->size.extS[0] = ALIGN(w, 32) * ALIGN(h, 16);
1422 buf->size.extS[1] = ALIGN(w/2, 16) * ALIGN(h/2, 8);
1423 buf->size.extS[2] = ALIGN(w/2, 16) * ALIGN(h/2, 8);
1424 break;
1425 default:
1426 ALOGE("ERR(%s):unmatched colorFormat(%d)", __FUNCTION__, colorFormat);
1427 return;
1428 break;
1429 }
1430}
1431
1432bool ExynosCameraHWInterface2::m_getRatioSize(int src_w, int src_h,
1433 int dst_w, int dst_h,
1434 int *crop_x, int *crop_y,
1435 int *crop_w, int *crop_h,
1436 int zoom)
1437{
1438 *crop_w = src_w;
1439 *crop_h = src_h;
1440
1441 if ( src_w != dst_w
1442 || src_h != dst_h) {
1443 float src_ratio = 1.0f;
1444 float dst_ratio = 1.0f;
1445
1446 // ex : 1024 / 768
1447 src_ratio = (float)src_w / (float)src_h;
1448
1449 // ex : 352 / 288
1450 dst_ratio = (float)dst_w / (float)dst_h;
1451
1452 if (dst_w * dst_h < src_w * src_h) {
1453 if (dst_ratio <= src_ratio) {
1454 // shrink w
1455 *crop_w = src_h * dst_ratio;
1456 *crop_h = src_h;
1457 } else {
1458 // shrink h
1459 *crop_w = src_w;
1460 *crop_h = src_w / dst_ratio;
1461 }
1462 } else {
1463 if (dst_ratio <= src_ratio) {
1464 // shrink w
1465 *crop_w = src_h * dst_ratio;
1466 *crop_h = src_h;
1467 } else {
1468 // shrink h
1469 *crop_w = src_w;
1470 *crop_h = src_w / dst_ratio;
1471 }
1472 }
1473 }
1474
1475 if (zoom != 0) {
1476 float zoomLevel = ((float)zoom + 10.0) / 10.0;
1477 *crop_w = (int)((float)*crop_w / zoomLevel);
1478 *crop_h = (int)((float)*crop_h / zoomLevel);
1479 }
1480
1481 #define CAMERA_CROP_WIDTH_RESTRAIN_NUM (0x2)
1482 unsigned int w_align = (*crop_w & (CAMERA_CROP_WIDTH_RESTRAIN_NUM - 1));
1483 if (w_align != 0) {
1484 if ( (CAMERA_CROP_WIDTH_RESTRAIN_NUM >> 1) <= w_align
1485 && *crop_w + (CAMERA_CROP_WIDTH_RESTRAIN_NUM - w_align) <= dst_w) {
1486 *crop_w += (CAMERA_CROP_WIDTH_RESTRAIN_NUM - w_align);
1487 }
1488 else
1489 *crop_w -= w_align;
1490 }
1491
1492 #define CAMERA_CROP_HEIGHT_RESTRAIN_NUM (0x2)
1493 unsigned int h_align = (*crop_h & (CAMERA_CROP_HEIGHT_RESTRAIN_NUM - 1));
1494 if (h_align != 0) {
1495 if ( (CAMERA_CROP_HEIGHT_RESTRAIN_NUM >> 1) <= h_align
1496 && *crop_h + (CAMERA_CROP_HEIGHT_RESTRAIN_NUM - h_align) <= dst_h) {
1497 *crop_h += (CAMERA_CROP_HEIGHT_RESTRAIN_NUM - h_align);
1498 }
1499 else
1500 *crop_h -= h_align;
1501 }
1502
1503 *crop_x = (src_w - *crop_w) >> 1;
1504 *crop_y = (src_h - *crop_h) >> 1;
1505
1506 if (*crop_x & (CAMERA_CROP_WIDTH_RESTRAIN_NUM >> 1))
1507 *crop_x -= 1;
1508
1509 if (*crop_y & (CAMERA_CROP_HEIGHT_RESTRAIN_NUM >> 1))
1510 *crop_y -= 1;
1511
1512 return true;
1513}
1514
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001515BayerBufManager::BayerBufManager()
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001516{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001517 ALOGV("DEBUG(%s): ", __FUNCTION__);
1518 for (int i = 0; i < NUM_BAYER_BUFFERS ; i++) {
1519 entries[i].status = BAYER_ON_HAL_EMPTY;
1520 entries[i].reqFrameCnt = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001521 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001522 sensorEnqueueHead = 0;
1523 sensorDequeueHead = 0;
1524 ispEnqueueHead = 0;
1525 ispDequeueHead = 0;
1526 numOnSensor = 0;
1527 numOnIsp = 0;
1528 numOnHalFilled = 0;
1529 numOnHalEmpty = NUM_BAYER_BUFFERS;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001530}
1531
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001532int BayerBufManager::GetIndexForSensorEnqueue()
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001533{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001534 int ret = 0;
1535 if (numOnHalEmpty == 0)
1536 ret = -1;
1537 else
1538 ret = sensorEnqueueHead;
1539 ALOGV("DEBUG(%s): returning (%d)", __FUNCTION__, ret);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001540 return ret;
1541}
1542
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001543int BayerBufManager::MarkSensorEnqueue(int index)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001544{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001545 ALOGV("DEBUG(%s) : BayerIndex[%d] ", __FUNCTION__, index);
1546
1547 // sanity check
1548 if (index != sensorEnqueueHead) {
1549 ALOGV("DEBUG(%s) : Abnormal BayerIndex[%d] - expected[%d]", __FUNCTION__, index, sensorEnqueueHead);
1550 return -1;
1551 }
1552 if (entries[index].status != BAYER_ON_HAL_EMPTY) {
1553 ALOGV("DEBUG(%s) : Abnormal status in BayerIndex[%d] = (%d) expected (%d)", __FUNCTION__,
1554 index, entries[index].status, BAYER_ON_HAL_EMPTY);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001555 return -1;
1556 }
1557
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001558 entries[index].status = BAYER_ON_SENSOR;
1559 entries[index].reqFrameCnt = 0;
1560 numOnHalEmpty--;
1561 numOnSensor++;
1562 sensorEnqueueHead = GetNextIndex(index);
1563 ALOGV("DEBUG(%s) END: HAL-e(%d) HAL-f(%d) Sensor(%d) ISP(%d) ",
1564 __FUNCTION__, numOnHalEmpty, numOnHalFilled, numOnSensor, numOnIsp);
1565 return 0;
1566}
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001567
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001568int BayerBufManager::MarkSensorDequeue(int index, int reqFrameCnt, nsecs_t *timeStamp)
1569{
1570 ALOGV("DEBUG(%s) : BayerIndex[%d] reqFrameCnt(%d)", __FUNCTION__, index, reqFrameCnt);
1571
1572 // sanity check
1573 if (index != sensorDequeueHead) {
1574 ALOGV("DEBUG(%s) : Abnormal BayerIndex[%d] - expected[%d]", __FUNCTION__, index, sensorDequeueHead);
1575 return -1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001576 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001577 if (entries[index].status != BAYER_ON_SENSOR) {
1578 ALOGV("DEBUG(%s) : Abnormal status in BayerIndex[%d] = (%d) expected (%d)", __FUNCTION__,
1579 index, entries[index].status, BAYER_ON_SENSOR);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001580 return -1;
1581 }
1582
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001583 entries[index].status = BAYER_ON_HAL_FILLED;
1584 entries[index].reqFrameCnt = reqFrameCnt;
1585 entries[index].timeStamp = *timeStamp;
1586 numOnHalFilled++;
1587 numOnSensor--;
1588 sensorDequeueHead = GetNextIndex(index);
1589 ALOGV("DEBUG(%s) END: HAL-e(%d) HAL-f(%d) Sensor(%d) ISP(%d) ",
1590 __FUNCTION__, numOnHalEmpty, numOnHalFilled, numOnSensor, numOnIsp);
1591 return 0;
1592}
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001593
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001594int BayerBufManager::GetIndexForIspEnqueue(int *reqFrameCnt)
1595{
1596 int ret = 0;
1597 if (numOnHalFilled == 0)
1598 ret = -1;
1599 else {
1600 *reqFrameCnt = entries[ispEnqueueHead].reqFrameCnt;
1601 ret = ispEnqueueHead;
1602 }
1603 ALOGV("DEBUG(%s): returning BayerIndex[%d]", __FUNCTION__, ret);
1604 return ret;
1605}
1606
1607int BayerBufManager::GetIndexForIspDequeue(int *reqFrameCnt)
1608{
1609 int ret = 0;
1610 if (numOnIsp == 0)
1611 ret = -1;
1612 else {
1613 *reqFrameCnt = entries[ispDequeueHead].reqFrameCnt;
1614 ret = ispDequeueHead;
1615 }
1616 ALOGV("DEBUG(%s): returning BayerIndex[%d]", __FUNCTION__, ret);
1617 return ret;
1618}
1619
1620int BayerBufManager::MarkIspEnqueue(int index)
1621{
1622 ALOGV("DEBUG(%s) : BayerIndex[%d] ", __FUNCTION__, index);
1623
1624 // sanity check
1625 if (index != ispEnqueueHead) {
1626 ALOGV("DEBUG(%s) : Abnormal BayerIndex[%d] - expected[%d]", __FUNCTION__, index, ispEnqueueHead);
1627 return -1;
1628 }
1629 if (entries[index].status != BAYER_ON_HAL_FILLED) {
1630 ALOGV("DEBUG(%s) : Abnormal status in BayerIndex[%d] = (%d) expected (%d)", __FUNCTION__,
1631 index, entries[index].status, BAYER_ON_HAL_FILLED);
1632 return -1;
1633 }
1634
1635 entries[index].status = BAYER_ON_ISP;
1636 numOnHalFilled--;
1637 numOnIsp++;
1638 ispEnqueueHead = GetNextIndex(index);
1639 ALOGV("DEBUG(%s) END: HAL-e(%d) HAL-f(%d) Sensor(%d) ISP(%d) ",
1640 __FUNCTION__, numOnHalEmpty, numOnHalFilled, numOnSensor, numOnIsp);
1641 return 0;
1642}
1643
1644int BayerBufManager::MarkIspDequeue(int index)
1645{
1646 ALOGV("DEBUG(%s) : BayerIndex[%d]", __FUNCTION__, index);
1647
1648 // sanity check
1649 if (index != ispDequeueHead) {
1650 ALOGV("DEBUG(%s) : Abnormal BayerIndex[%d] - expected[%d]", __FUNCTION__, index, ispDequeueHead);
1651 return -1;
1652 }
1653 if (entries[index].status != BAYER_ON_ISP) {
1654 ALOGV("DEBUG(%s) : Abnormal status in BayerIndex[%d] = (%d) expected (%d)", __FUNCTION__,
1655 index, entries[index].status, BAYER_ON_ISP);
1656 return -1;
1657 }
1658
1659 entries[index].status = BAYER_ON_HAL_EMPTY;
1660 entries[index].reqFrameCnt = 0;
1661 numOnHalEmpty++;
1662 numOnIsp--;
1663 ispDequeueHead = GetNextIndex(index);
1664 ALOGV("DEBUG(%s) END: HAL-e(%d) HAL-f(%d) Sensor(%d) ISP(%d) ",
1665 __FUNCTION__, numOnHalEmpty, numOnHalFilled, numOnSensor, numOnIsp);
1666 return 0;
1667}
1668
1669int BayerBufManager::GetNumOnSensor()
1670{
1671 return numOnSensor;
1672}
1673
1674int BayerBufManager::GetNumOnHalFilled()
1675{
1676 return numOnHalFilled;
1677}
1678
1679int BayerBufManager::GetNumOnIsp()
1680{
1681 return numOnIsp;
1682}
1683
1684int BayerBufManager::GetNextIndex(int index)
1685{
1686 index++;
1687 if (index >= NUM_BAYER_BUFFERS)
1688 index = 0;
1689
1690 return index;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001691}
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001692
1693void ExynosCameraHWInterface2::m_mainThreadFunc(SignalDrivenThread * self)
1694{
1695 camera_metadata_t *currentRequest = NULL;
1696 camera_metadata_t *currentFrame = NULL;
1697 size_t numEntries = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001698 size_t frameSize = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001699 camera_metadata_t * preparedFrame = NULL;
1700 camera_metadata_t *deregisteredRequest = NULL;
1701 uint32_t currentSignal = self->GetProcessingSignal();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001702 MainThread * selfThread = ((MainThread*)self);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001703 int res = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001704
1705 ALOGV("DEBUG(%s): m_mainThreadFunc (%x)", __FUNCTION__, currentSignal);
1706
1707 if (currentSignal & SIGNAL_THREAD_RELEASE) {
1708 ALOGV("DEBUG(%s): processing SIGNAL_THREAD_RELEASE", __FUNCTION__);
1709
1710 ALOGV("DEBUG(%s): processing SIGNAL_THREAD_RELEASE DONE", __FUNCTION__);
1711 selfThread->SetSignal(SIGNAL_THREAD_TERMINATE);
1712 return;
1713 }
1714
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001715 if (currentSignal & SIGNAL_MAIN_REQ_Q_NOT_EMPTY) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001716 ALOGV("DEBUG(%s): MainThread processing SIGNAL_MAIN_REQ_Q_NOT_EMPTY", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001717 if (m_requestManager->IsRequestQueueFull()==false
1718 && m_requestManager->GetNumEntries()<NUM_MAX_DEQUEUED_REQUEST) {
1719 m_requestQueueOps->dequeue_request(m_requestQueueOps, &currentRequest);
1720 if (NULL == currentRequest) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001721 ALOGV("DEBUG(%s): dequeue_request returned NULL ", __FUNCTION__);
1722 m_isRequestQueueNull = true;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001723 }
1724 else {
1725 m_requestManager->RegisterRequest(currentRequest);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001726
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001727 m_numOfRemainingReqInSvc = m_requestQueueOps->request_count(m_requestQueueOps);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001728 ALOGV("DEBUG(%s): remaining req cnt (%d)", __FUNCTION__, m_numOfRemainingReqInSvc);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001729 if (m_requestManager->IsRequestQueueFull()==false
1730 && m_requestManager->GetNumEntries()<NUM_MAX_DEQUEUED_REQUEST)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001731 selfThread->SetSignal(SIGNAL_MAIN_REQ_Q_NOT_EMPTY); // dequeue repeatedly
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001732
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001733 m_sensorThread->SetSignal(SIGNAL_SENSOR_START_REQ_PROCESSING);
1734 }
1735 }
1736 else {
1737 m_isRequestQueuePending = true;
1738 }
1739 }
1740
1741 if (currentSignal & SIGNAL_MAIN_STREAM_OUTPUT_DONE) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001742 ALOGV("DEBUG(%s): MainThread processing SIGNAL_MAIN_STREAM_OUTPUT_DONE", __FUNCTION__);
1743 /*while (1)*/ {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001744 m_requestManager->PrepareFrame(&numEntries, &frameSize, &preparedFrame);
1745 m_requestManager->DeregisterRequest(&deregisteredRequest);
1746 m_requestQueueOps->free_request(m_requestQueueOps, deregisteredRequest);
1747 m_frameQueueOps->dequeue_frame(m_frameQueueOps, numEntries, frameSize, &currentFrame);
1748 if (currentFrame==NULL) {
1749 ALOGD("DBG(%s): frame dequeue returned NULL",__FUNCTION__ );
1750 }
1751 else {
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07001752 ALOGV("DEBUG(%s): frame dequeue done. numEntries(%d) frameSize(%d)",__FUNCTION__ , numEntries, frameSize);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001753 }
1754 res = append_camera_metadata(currentFrame, preparedFrame);
1755 if (res==0) {
1756 ALOGV("DEBUG(%s): frame metadata append success",__FUNCTION__);
1757 m_frameQueueOps->enqueue_frame(m_frameQueueOps, currentFrame);
1758 }
1759 else {
1760 ALOGE("ERR(%s): frame metadata append fail (%d)",__FUNCTION__, res);
1761 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001762 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001763 if (!m_isRequestQueueNull) {
1764 selfThread->SetSignal(SIGNAL_MAIN_REQ_Q_NOT_EMPTY);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001765 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001766
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001767 if (getInProgressCount()>0) {
1768 ALOGV("DEBUG(%s): STREAM_OUTPUT_DONE and signalling REQ_PROCESSING",__FUNCTION__);
1769 m_sensorThread->SetSignal(SIGNAL_SENSOR_START_REQ_PROCESSING);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001770 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001771 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001772 ALOGV("DEBUG(%s): MainThread Exit", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001773 return;
1774}
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001775
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001776void ExynosCameraHWInterface2::m_sensorThreadInitialize(SignalDrivenThread * self)
1777{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001778 ALOGV("DEBUG(%s): ", __FUNCTION__ );
1779 SensorThread * selfThread = ((SensorThread*)self);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001780 char node_name[30];
1781 int fd = 0;
1782 int i =0, j=0;
1783
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001784 if(m_cameraId == 0)
1785 m_camera_info.sensor_id = SENSOR_NAME_S5K4E5;
1786 else
1787 m_camera_info.sensor_id = SENSOR_NAME_S5K6A3;
1788
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001789 memset(&m_camera_info.dummy_shot, 0x00, sizeof(struct camera2_shot_ext));
1790 m_camera_info.dummy_shot.shot.ctl.request.metadataMode = METADATA_MODE_FULL;
1791 m_camera_info.dummy_shot.shot.magicNumber = 0x23456789;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001792
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001793 m_camera_info.dummy_shot.dis_bypass = 1;
1794 m_camera_info.dummy_shot.dnr_bypass = 1;
1795
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001796 /*sensor setting*/
1797 m_camera_info.dummy_shot.shot.ctl.sensor.exposureTime = 0;
1798 m_camera_info.dummy_shot.shot.ctl.sensor.frameDuration = 0;
1799 m_camera_info.dummy_shot.shot.ctl.sensor.sensitivity = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001800
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001801 m_camera_info.dummy_shot.shot.ctl.scaler.cropRegion[0] = 0;
1802 m_camera_info.dummy_shot.shot.ctl.scaler.cropRegion[1] = 0;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001803 //m_camera_info.dummy_shot.shot.ctl.scaler.cropRegion[2] = 1920;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001804
1805 /*request setting*/
1806 m_camera_info.dummy_shot.request_sensor = 1;
1807 m_camera_info.dummy_shot.request_scc = 0;
1808 m_camera_info.dummy_shot.request_scp = 0;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001809 m_camera_info.dummy_shot.shot.ctl.request.outputStreams[0] = 0;
1810 m_camera_info.dummy_shot.shot.ctl.request.outputStreams[1] = 0;
1811 m_camera_info.dummy_shot.shot.ctl.request.outputStreams[2] = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001812
1813 /*sensor init*/
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001814 memset(&node_name, 0x00, sizeof(char[30]));
1815 sprintf(node_name, "%s%d", NODE_PREFIX, 40);
1816 fd = exynos_v4l2_open(node_name, O_RDWR, 0);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001817
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001818 if (fd < 0) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001819 ALOGE("ERR(%s): failed to open sensor video node (%s) fd (%d)", __FUNCTION__,node_name, fd);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001820 }
1821 else {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001822 ALOGV("DEBUG(%s): sensor video node opened(%s) fd (%d)", __FUNCTION__,node_name, fd);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001823 }
1824 m_camera_info.sensor.fd = fd;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001825
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07001826 m_camera_info.sensor.width = m_camera2->getSensorRawW();
1827 m_camera_info.sensor.height = m_camera2->getSensorRawH();
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001828
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001829 m_camera_info.sensor.format = V4L2_PIX_FMT_SBGGR16;
1830 m_camera_info.sensor.planes = 2;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001831 m_camera_info.sensor.buffers = NUM_BAYER_BUFFERS;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001832 m_camera_info.sensor.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
Alex Ray24231222012-06-27 15:18:15 -07001833 m_camera_info.sensor.memory = V4L2_MEMORY_DMABUF;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001834 m_camera_info.sensor.ionClient = m_ionCameraClient;
1835
1836 for(i = 0; i < m_camera_info.sensor.buffers; i++){
1837 initCameraMemory(&m_camera_info.sensor.buffer[i], m_camera_info.sensor.planes);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001838 m_camera_info.sensor.buffer[i].size.extS[0] = m_camera_info.sensor.width*m_camera_info.sensor.height*2;
1839 m_camera_info.sensor.buffer[i].size.extS[1] = 8*1024; // HACK, driver use 8*1024, should be use predefined value
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001840 allocCameraMemory(m_camera_info.sensor.ionClient, &m_camera_info.sensor.buffer[i], m_camera_info.sensor.planes);
1841 }
1842
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001843 m_initFlag1 = true;
1844
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001845
1846 while (!m_initFlag2) // temp
1847 usleep(100000);
1848 ALOGV("DEBUG(%s): END of SensorThreadInitialize ", __FUNCTION__);
1849 return;
1850}
1851
1852
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001853void ExynosCameraHWInterface2::DumpInfoWithShot(struct camera2_shot_ext * shot_ext)
1854{
1855 ALOGV("#### common Section");
1856 ALOGV("#### magic(%x) ",
1857 shot_ext->shot.magicNumber);
1858 ALOGV("#### ctl Section");
1859 ALOGV("#### metamode(%d) exposureTime(%lld) duration(%lld) ISO(%d) ",
1860 shot_ext->shot.ctl.request.metadataMode,
1861 shot_ext->shot.ctl.sensor.exposureTime,
1862 shot_ext->shot.ctl.sensor.frameDuration,
1863 shot_ext->shot.ctl.sensor.sensitivity);
1864
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001865 ALOGV("#### OutputStream Sensor(%d) SCP(%d) SCC(%d) pv(%d) rec(%d)",
1866 shot_ext->request_sensor, shot_ext->request_scp, shot_ext->request_scc,
1867 shot_ext->shot.ctl.request.outputStreams[0],
1868 shot_ext->shot.ctl.request.outputStreams[2]);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001869
1870 ALOGV("#### DM Section");
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001871 ALOGV("#### metamode(%d) exposureTime(%lld) duration(%lld) ISO(%d) timestamp(%lld)",
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001872 shot_ext->shot.dm.request.metadataMode,
1873 shot_ext->shot.dm.sensor.exposureTime,
1874 shot_ext->shot.dm.sensor.frameDuration,
1875 shot_ext->shot.dm.sensor.sensitivity,
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001876 shot_ext->shot.dm.sensor.timeStamp);
1877}
1878
1879void ExynosCameraHWInterface2::m_sensorThreadFunc(SignalDrivenThread * self)
1880{
1881 uint32_t currentSignal = self->GetProcessingSignal();
1882 SensorThread * selfThread = ((SensorThread*)self);
1883 int index;
1884 status_t res;
1885 nsecs_t frameTime;
1886 int bayersOnSensor = 0, bayersOnIsp = 0;
1887 ALOGV("DEBUG(%s): m_sensorThreadFunc (%x)", __FUNCTION__, currentSignal);
1888
1889 if (currentSignal & SIGNAL_THREAD_RELEASE) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001890 ALOGD("(%s): ENTER processing SIGNAL_THREAD_RELEASE", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001891
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001892 ALOGV("(%s): calling sensor streamoff", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001893 cam_int_streamoff(&(m_camera_info.sensor));
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001894 ALOGV("(%s): calling sensor streamoff done", __FUNCTION__);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001895
1896 m_camera_info.sensor.buffers = 0;
1897 ALOGV("DEBUG(%s): sensor calling reqbuf 0 ", __FUNCTION__);
1898 cam_int_reqbufs(&(m_camera_info.sensor));
1899 ALOGV("DEBUG(%s): sensor calling reqbuf 0 done", __FUNCTION__);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001900
1901 ALOGV("(%s): calling ISP streamoff", __FUNCTION__);
1902 isp_int_streamoff(&(m_camera_info.isp));
1903 ALOGV("(%s): calling ISP streamoff done", __FUNCTION__);
1904
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001905 m_camera_info.isp.buffers = 0;
1906 ALOGV("DEBUG(%s): isp calling reqbuf 0 ", __FUNCTION__);
1907 cam_int_reqbufs(&(m_camera_info.isp));
1908 ALOGV("DEBUG(%s): isp calling reqbuf 0 done", __FUNCTION__);
1909
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001910 exynos_v4l2_s_ctrl(m_camera_info.sensor.fd, V4L2_CID_IS_S_STREAM, IS_DISABLE_STREAM);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001911
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001912 ALOGD("(%s): EXIT processing SIGNAL_THREAD_RELEASE", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001913 selfThread->SetSignal(SIGNAL_THREAD_TERMINATE);
1914 return;
1915 }
1916
1917 if (currentSignal & SIGNAL_SENSOR_START_REQ_PROCESSING)
1918 {
1919 ALOGV("DEBUG(%s): SensorThread processing SIGNAL_SENSOR_START_REQ_PROCESSING", __FUNCTION__);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001920 int targetStreamIndex = 0, i=0;
1921 int matchedFrameCnt, processingReqIndex;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001922 struct camera2_shot_ext *shot_ext;
1923 if (!m_isSensorStarted)
1924 {
1925 m_isSensorStarted = true;
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001926 ALOGD("(%s): calling preview streamon", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001927 cam_int_streamon(&(m_streamThreads[0]->m_parameters.node));
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001928 ALOGD("(%s): calling isp streamon done", __FUNCTION__);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001929 for (i = 0; i < m_camera_info.isp.buffers; i++) {
1930 ALOGV("DEBUG(%s): isp initial QBUF [%d]", __FUNCTION__, i);
1931 cam_int_qbuf(&(m_camera_info.isp), i);
1932 }
1933
1934 cam_int_streamon(&(m_camera_info.isp));
1935
1936 for (i = 0; i < m_camera_info.isp.buffers; i++) {
1937 ALOGV("DEBUG(%s): isp initial DQBUF [%d]", __FUNCTION__, i);
1938 cam_int_dqbuf(&(m_camera_info.isp));
1939 }
1940
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001941 ALOGV("DEBUG(%s): calling isp sctrl done", __FUNCTION__);
1942 exynos_v4l2_s_ctrl(m_camera_info.sensor.fd, V4L2_CID_IS_S_STREAM, IS_ENABLE_STREAM);
1943 ALOGV("DEBUG(%s): calling sensor sctrl done", __FUNCTION__);
1944
1945 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001946
Alex Ray3f0357b2012-07-30 16:42:12 -07001947 ALOGV("### Sensor DQBUF start");
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001948 index = cam_int_dqbuf(&(m_camera_info.sensor));
1949 frameTime = systemTime();
Alex Ray3f0357b2012-07-30 16:42:12 -07001950 ALOGV("### Sensor DQBUF done BayerIndex(%d)", index);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001951 shot_ext = (struct camera2_shot_ext *)(m_camera_info.sensor.buffer[index].virt.extP[1]);
1952 matchedFrameCnt = m_requestManager->FindFrameCnt(shot_ext);
Sungjoong Kangbe494d12012-08-04 15:36:56 -07001953 ALOGV("### Matched(%d) last(%d), dqbuf timestamp(%lld)", matchedFrameCnt, lastFrameCnt
1954 , shot_ext->shot.dm.sensor.timeStamp);
Sungjoong Kanga07cbd92012-07-27 12:03:29 -07001955 if (matchedFrameCnt != -1) {
1956 while (matchedFrameCnt == lastFrameCnt) {
1957 m_BayerManager->MarkSensorDequeue(index, -1, &frameTime);
Alex Ray3f0357b2012-07-30 16:42:12 -07001958 ALOGV("### Sensor DQBUF start");
Sungjoong Kanga07cbd92012-07-27 12:03:29 -07001959 index = cam_int_dqbuf(&(m_camera_info.sensor));
1960 frameTime = systemTime();
Alex Ray3f0357b2012-07-30 16:42:12 -07001961 ALOGV("### Sensor DQBUF done BayerIndex(%d)", index);
Sungjoong Kanga07cbd92012-07-27 12:03:29 -07001962 shot_ext = (struct camera2_shot_ext *)(m_camera_info.sensor.buffer[index].virt.extP[1]);
1963 matchedFrameCnt = m_requestManager->FindFrameCnt(shot_ext);
Alex Ray3f0357b2012-07-30 16:42:12 -07001964 ALOGV("### Matched(%d) last(%d)", matchedFrameCnt, lastFrameCnt);
Sungjoong Kanga07cbd92012-07-27 12:03:29 -07001965 }
1966 lastFrameCnt = matchedFrameCnt;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001967 m_scp_closing = false;
1968 m_scp_closed = false;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001969 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001970 m_BayerManager->MarkSensorDequeue(index, matchedFrameCnt, &frameTime);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001971
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001972 m_requestManager->RegisterTimestamp(matchedFrameCnt, &frameTime);
Alex Ray386436c2012-07-30 16:55:15 -07001973 ALOGV("### Sensor DQed BayerIndex[%d] passing to ISP. frameCnt(%d) timestamp(%lld)",
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001974 index, matchedFrameCnt, frameTime);
1975
1976 if (!(m_ispThread.get()))
1977 return;
1978
1979 m_ispThread->SetSignal(SIGNAL_ISP_START_BAYER_INPUT);
1980
1981 while (m_BayerManager->GetNumOnSensor() <= NUM_SENSOR_QBUF) {
1982
1983 index = m_BayerManager->GetIndexForSensorEnqueue();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001984 if (index == -1) {
1985 ALOGE("ERR(%s) No free Bayer buffer", __FUNCTION__);
1986 break;
1987 }
1988 processingReqIndex = m_requestManager->MarkProcessingRequest(&(m_camera_info.sensor.buffer[index]));
1989
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001990 shot_ext = (struct camera2_shot_ext *)(m_camera_info.sensor.buffer[index].virt.extP[1]);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001991 if (processingReqIndex == -1) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001992 ALOGV("DEBUG(%s) req underrun => inserting bubble to BayerIndex(%d)", __FUNCTION__, index);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001993 memcpy(shot_ext, &(m_camera_info.dummy_shot), sizeof(struct camera2_shot_ext));
1994 }
1995
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001996 m_BayerManager->MarkSensorEnqueue(index);
1997 if (m_scp_closing || m_scp_closed) {
1998 ALOGV("(%s): SCP_CLOSING(%d) SCP_CLOSED(%d)", __FUNCTION__, m_scp_closing, m_scp_closed);
1999 shot_ext->request_scc = 0;
2000 shot_ext->request_scp = 0;
2001 shot_ext->request_sensor = 0;
2002 }
Alex Ray386436c2012-07-30 16:55:15 -07002003 ALOGV("### Sensor QBUF start BayerIndex[%d]", index);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002004 cam_int_qbuf(&(m_camera_info.sensor), index);
Alex Ray386436c2012-07-30 16:55:15 -07002005 ALOGV("### Sensor QBUF done");
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002006 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002007 if (!m_closing){
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002008 selfThread->SetSignal(SIGNAL_SENSOR_START_REQ_PROCESSING);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002009 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002010 return;
2011 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002012 return;
2013}
2014
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002015void ExynosCameraHWInterface2::m_ispThreadInitialize(SignalDrivenThread * self)
2016{
2017 ALOGV("DEBUG(%s): ", __FUNCTION__ );
2018 IspThread * selfThread = ((IspThread*)self);
2019 char node_name[30];
2020 int fd = 0;
2021 int i =0, j=0;
2022
2023
2024 while (!m_initFlag1) //temp
2025 usleep(100000);
2026
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002027 /*isp init*/
2028 memset(&node_name, 0x00, sizeof(char[30]));
2029 sprintf(node_name, "%s%d", NODE_PREFIX, 41);
2030 fd = exynos_v4l2_open(node_name, O_RDWR, 0);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002031
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002032 if (fd < 0) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002033 ALOGE("ERR(%s): failed to open isp video node (%s) fd (%d)", __FUNCTION__,node_name, fd);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002034 }
2035 else {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002036 ALOGV("DEBUG(%s): isp video node opened(%s) fd (%d)", __FUNCTION__,node_name, fd);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002037 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002038 m_camera_info.isp.fd = fd;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002039
2040 m_camera_info.isp.width = m_camera_info.sensor.width;
2041 m_camera_info.isp.height = m_camera_info.sensor.height;
2042 m_camera_info.isp.format = m_camera_info.sensor.format;
2043 m_camera_info.isp.planes = m_camera_info.sensor.planes;
2044 m_camera_info.isp.buffers = m_camera_info.sensor.buffers;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002045 m_camera_info.isp.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Alex Ray24231222012-06-27 15:18:15 -07002046 m_camera_info.isp.memory = V4L2_MEMORY_DMABUF;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002047
2048 for(i = 0; i < m_camera_info.isp.buffers; i++){
2049 initCameraMemory(&m_camera_info.isp.buffer[i], m_camera_info.isp.planes);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002050 m_camera_info.isp.buffer[i].size.extS[0] = m_camera_info.sensor.buffer[i].size.extS[0];
2051 m_camera_info.isp.buffer[i].size.extS[1] = m_camera_info.sensor.buffer[i].size.extS[1];
2052 m_camera_info.isp.buffer[i].fd.extFd[0] = m_camera_info.sensor.buffer[i].fd.extFd[0];
2053 m_camera_info.isp.buffer[i].fd.extFd[1] = m_camera_info.sensor.buffer[i].fd.extFd[1];
2054 m_camera_info.isp.buffer[i].virt.extP[0] = m_camera_info.sensor.buffer[i].virt.extP[0];
2055 m_camera_info.isp.buffer[i].virt.extP[1] = m_camera_info.sensor.buffer[i].virt.extP[1];
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002056 };
2057
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002058 cam_int_s_input(&(m_camera_info.isp), m_camera_info.sensor_id);
2059 cam_int_s_fmt(&(m_camera_info.isp));
2060 ALOGV("DEBUG(%s): isp calling reqbuf", __FUNCTION__);
2061 cam_int_reqbufs(&(m_camera_info.isp));
2062 ALOGV("DEBUG(%s): isp calling querybuf", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002063 ALOGV("DEBUG(%s): isp mem alloc done", __FUNCTION__);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002064
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002065 cam_int_s_input(&(m_camera_info.sensor), m_camera_info.sensor_id);
2066 ALOGV("DEBUG(%s): sensor s_input done", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002067 if (cam_int_s_fmt(&(m_camera_info.sensor))< 0) {
2068 ALOGE("ERR(%s): sensor s_fmt fail", __FUNCTION__);
2069 }
2070 ALOGV("DEBUG(%s): sensor s_fmt done", __FUNCTION__);
2071 cam_int_reqbufs(&(m_camera_info.sensor));
2072 ALOGV("DEBUG(%s): sensor reqbuf done", __FUNCTION__);
2073 for (i = 0; i < m_camera_info.sensor.buffers; i++) {
2074 ALOGV("DEBUG(%s): sensor initial QBUF [%d]", __FUNCTION__, i);
2075 memcpy( m_camera_info.sensor.buffer[i].virt.extP[1], &(m_camera_info.dummy_shot),
2076 sizeof(struct camera2_shot_ext));
2077 m_camera_info.dummy_shot.shot.ctl.sensor.frameDuration = 33*1000*1000; // apply from frame #1
2078
2079 cam_int_qbuf(&(m_camera_info.sensor), i);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002080 m_BayerManager->MarkSensorEnqueue(i);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002081 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002082 ALOGE("== stream_on :: m_camera_info.sensor");
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002083 cam_int_streamon(&(m_camera_info.sensor));
2084
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002085
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002086
2087/*capture init*/
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002088 memset(&node_name, 0x00, sizeof(char[30]));
2089 sprintf(node_name, "%s%d", NODE_PREFIX, 42);
2090 fd = exynos_v4l2_open(node_name, O_RDWR, 0);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002091
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002092 if (fd < 0) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002093 ALOGE("ERR(%s): failed to open capture video node (%s) fd (%d)", __FUNCTION__,node_name, fd);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002094 }
2095 else {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002096 ALOGV("DEBUG(%s): capture video node opened(%s) fd (%d)", __FUNCTION__,node_name, fd);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002097 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002098 m_camera_info.capture.fd = fd;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002099
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07002100 m_camera_info.capture.width = m_camera2->getSensorW();
2101 m_camera_info.capture.height = m_camera2->getSensorH();
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002102 m_camera_info.capture.format = V4L2_PIX_FMT_YUYV;
2103 m_camera_info.capture.planes = 1;
2104 m_camera_info.capture.buffers = 8;
2105 m_camera_info.capture.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
Alex Ray24231222012-06-27 15:18:15 -07002106 m_camera_info.capture.memory = V4L2_MEMORY_DMABUF;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002107 m_camera_info.capture.ionClient = m_ionCameraClient;
2108
2109 for(i = 0; i < m_camera_info.capture.buffers; i++){
2110 initCameraMemory(&m_camera_info.capture.buffer[i], m_camera_info.capture.planes);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002111 m_camera_info.capture.buffer[i].size.extS[0] = m_camera_info.capture.width*m_camera_info.capture.height*2;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002112 allocCameraMemory(m_camera_info.capture.ionClient, &m_camera_info.capture.buffer[i], m_camera_info.capture.planes);
2113 }
2114
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002115 cam_int_s_input(&(m_camera_info.capture), m_camera_info.sensor_id);
2116 cam_int_s_fmt(&(m_camera_info.capture));
2117 ALOGV("DEBUG(%s): capture calling reqbuf", __FUNCTION__);
2118 cam_int_reqbufs(&(m_camera_info.capture));
2119 ALOGV("DEBUG(%s): capture calling querybuf", __FUNCTION__);
2120
2121 for (i = 0; i < m_camera_info.capture.buffers; i++) {
2122 ALOGV("DEBUG(%s): capture initial QBUF [%d]", __FUNCTION__, i);
2123 cam_int_qbuf(&(m_camera_info.capture), i);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002124 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002125
2126 ALOGE("== stream_on :: m_camera_info.capture");
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002127 cam_int_streamon(&(m_camera_info.capture));
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002128
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002129 m_initFlag2 = true;
2130 ALOGV("DEBUG(%s): END of IspThreadInitialize ", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002131 return;
2132}
2133
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002134
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002135void ExynosCameraHWInterface2::m_ispThreadFunc(SignalDrivenThread * self)
2136{
2137 uint32_t currentSignal = self->GetProcessingSignal();
2138 IspThread * selfThread = ((IspThread*)self);
2139 int index;
2140 status_t res;
2141 ALOGV("DEBUG(%s): m_ispThreadFunc (%x)", __FUNCTION__, currentSignal);
2142
2143 if (currentSignal & SIGNAL_THREAD_RELEASE) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002144 ALOGD("(%s): ENTER processing SIGNAL_THREAD_RELEASE", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002145
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002146 ALOGV("(%s): calling capture streamoff", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002147 cam_int_streamoff(&(m_camera_info.capture));
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002148 ALOGV("(%s): calling capture streamoff done", __FUNCTION__);
2149
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002150 m_camera_info.capture.buffers = 0;
2151 ALOGV("DEBUG(%s): capture calling reqbuf 0 ", __FUNCTION__);
2152 cam_int_reqbufs(&(m_camera_info.capture));
2153 ALOGV("DEBUG(%s): capture calling reqbuf 0 done", __FUNCTION__);
2154
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002155 ALOGD("(%s): EXIT processing SIGNAL_THREAD_RELEASE ", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002156 selfThread->SetSignal(SIGNAL_THREAD_TERMINATE);
2157 return;
2158 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002159
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002160 if (currentSignal & SIGNAL_ISP_START_BAYER_INPUT)
2161 {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002162 struct camera2_shot_ext *shot_ext;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002163 int bayerIndexToEnqueue = 0;
2164 int processingFrameCnt = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002165
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002166 ALOGV("DEBUG(%s): IspThread processing SIGNAL_ISP_START_BAYER_INPUT", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002167
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002168 bayerIndexToEnqueue = m_BayerManager->GetIndexForIspEnqueue(&processingFrameCnt);
2169 shot_ext = (struct camera2_shot_ext *)(m_camera_info.sensor.buffer[bayerIndexToEnqueue].virt.extP[1]);
2170
2171 ALOGV("### isp QBUF start bayerIndex[%d] for frameCnt(%d)", bayerIndexToEnqueue, processingFrameCnt);
2172
2173 if (processingFrameCnt != -1) {
2174 ALOGV("### writing output stream info");
2175 m_requestManager->UpdateOutputStreamInfo(shot_ext, processingFrameCnt);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002176 }
2177 else {
2178 memcpy(shot_ext, &(m_camera_info.dummy_shot), sizeof(struct camera2_shot_ext));
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002179 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002180 if (m_scp_flushing) {
2181 shot_ext->request_scp = 1;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002182 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002183 if (m_scp_closing || m_scp_closed) {
2184 ALOGV("(%s): SCP_CLOSING(%d) SCP_CLOSED(%d)", __FUNCTION__, m_scp_closing, m_scp_closed);
2185 shot_ext->request_scc = 0;
2186 shot_ext->request_scp = 0;
2187 shot_ext->request_sensor = 0;
2188 }
2189 cam_int_qbuf(&(m_camera_info.isp), bayerIndexToEnqueue);
2190 ALOGV("### isp QBUF done bayerIndex[%d] scp(%d)", bayerIndexToEnqueue, shot_ext->request_scp);
2191 m_BayerManager->MarkIspEnqueue(bayerIndexToEnqueue);
2192
2193 if (m_BayerManager->GetNumOnHalFilled() != 0) {
2194 // input has priority
2195 selfThread->SetSignal(SIGNAL_ISP_START_BAYER_INPUT);
2196 return;
2197 }
2198 else {
2199 selfThread->SetSignal(SIGNAL_ISP_START_BAYER_DEQUEUE);
2200 }
2201 }
2202
2203 if (currentSignal & SIGNAL_ISP_START_BAYER_DEQUEUE)
2204 {
2205 struct camera2_shot_ext *shot_ext;
2206 int bayerIndexToDequeue = 0;
2207 int processingFrameCnt = 0;
2208 ALOGV("DEBUG(%s): IspThread processing SIGNAL_ISP_START_BAYER_DEQUEUE", __FUNCTION__);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002209 bayerIndexToDequeue = m_BayerManager->GetIndexForIspDequeue(&processingFrameCnt);
2210 m_ispProcessingFrameCnt = processingFrameCnt;
2211 m_previewOutput = 0;
2212 m_recordOutput = 0;
2213 shot_ext = (struct camera2_shot_ext *)(m_camera_info.sensor.buffer[bayerIndexToDequeue].virt.extP[1]);
2214 if (processingFrameCnt != -1 || m_scp_flushing) // bubble
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002215 {
2216 if (shot_ext->request_scc) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002217 m_streamThreads[1]->SetSignal(SIGNAL_STREAM_DATA_COMING);
2218 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002219 m_previewOutput = shot_ext->shot.ctl.request.outputStreams[0];
2220 m_recordOutput = shot_ext->shot.ctl.request.outputStreams[2];
2221 if (m_previewOutput || m_recordOutput) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002222 m_streamThreads[0]->SetSignal(SIGNAL_STREAM_DATA_COMING);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002223 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002224 }
Alex Ray3f0357b2012-07-30 16:42:12 -07002225 ALOGV("### isp DQBUF start");
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002226 index = cam_int_dqbuf(&(m_camera_info.isp));
Alex Ray3f0357b2012-07-30 16:42:12 -07002227 ALOGV("### isp DQBUF done bayerIndex(%d) for frameCnt(%d)", index, processingFrameCnt);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002228 shot_ext = (struct camera2_shot_ext *)(m_camera_info.sensor.buffer[index].virt.extP[1]);
2229 ALOGV("(%s): SCP_CLOSING check sensor(%d) scc(%d) scp(%d) ", __FUNCTION__,
2230 shot_ext->request_sensor, shot_ext->request_scc, shot_ext->request_scp);
2231 if (shot_ext->request_scc + shot_ext->request_scp + shot_ext->request_sensor == 0) {
2232 ALOGV("(%s): SCP_CLOSING check OK ", __FUNCTION__);
2233 m_scp_closed = true;
2234 }
2235 else
2236 m_scp_closed = false;
2237 if (processingFrameCnt != -1) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002238 m_requestManager->ApplyDynamicMetadata(shot_ext, processingFrameCnt);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002239 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002240 m_BayerManager->MarkIspDequeue(index);
2241 if (m_BayerManager->GetNumOnIsp() != 0) {
2242 selfThread->SetSignal(SIGNAL_ISP_START_BAYER_DEQUEUE);
2243 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002244 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002245
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002246 return;
2247}
2248
2249void ExynosCameraHWInterface2::m_streamThreadInitialize(SignalDrivenThread * self)
2250{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002251 StreamThread * selfThread = ((StreamThread*)self);
2252 ALOGV("DEBUG(%s): ", __FUNCTION__ );
2253 memset(&(selfThread->m_parameters), 0, sizeof(stream_parameters_t));
2254 selfThread->m_isBufferInit = false;
2255
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002256 return;
2257}
2258
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002259void ExynosCameraHWInterface2::m_streamThreadFunc(SignalDrivenThread * self)
2260{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002261 uint32_t currentSignal = self->GetProcessingSignal();
2262 StreamThread * selfThread = ((StreamThread*)self);
2263 stream_parameters_t *selfStreamParms = &(selfThread->m_parameters);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002264 record_parameters_t *selfRecordParms = &(selfThread->m_recordParameters);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002265 node_info_t *currentNode = &(selfStreamParms->node);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002266
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002267 ALOGV("DEBUG(%s): m_streamThreadFunc[%d] (%x)", __FUNCTION__, selfThread->m_index, currentSignal);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002268
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002269 if (currentSignal & SIGNAL_STREAM_CHANGE_PARAMETER) {
2270 ALOGV("DEBUG(%s): processing SIGNAL_STREAM_CHANGE_PARAMETER", __FUNCTION__);
2271 selfThread->applyChange();
2272 if (selfStreamParms->streamType==1) {
2273 m_resizeBuf.size.extS[0] = ALIGN(selfStreamParms->outputWidth, 16) * ALIGN(selfStreamParms->outputHeight, 16) * 2;
2274 m_resizeBuf.size.extS[1] = 0;
2275 m_resizeBuf.size.extS[2] = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002276
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002277 if (allocCameraMemory(selfStreamParms->ionClient, &m_resizeBuf, 1) == -1) {
2278 ALOGE("ERR(%s): Failed to allocate resize buf", __FUNCTION__);
2279 }
2280 }
2281 ALOGV("DEBUG(%s): processing SIGNAL_STREAM_CHANGE_PARAMETER DONE", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002282 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002283
2284 if (currentSignal & SIGNAL_THREAD_RELEASE) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002285 int i, index = -1, cnt_to_dq = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002286 status_t res;
2287 ALOGV("DEBUG(%s): processing SIGNAL_THREAD_RELEASE", __FUNCTION__);
2288
2289
2290
2291 if (selfThread->m_isBufferInit) {
2292 for ( i=0 ; i < selfStreamParms->numSvcBuffers; i++) {
2293 ALOGV("DEBUG(%s): checking buffer index[%d] - status(%d)",
2294 __FUNCTION__, i, selfStreamParms->svcBufStatus[i]);
2295 if (selfStreamParms->svcBufStatus[i] ==ON_DRIVER) cnt_to_dq++;
2296 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002297
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002298 m_scp_closing = true;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002299 ALOGV("DEBUG(%s): calling stream(%d) streamoff (fd:%d)", __FUNCTION__,
2300 selfThread->m_index, selfStreamParms->fd);
2301 cam_int_streamoff(&(selfStreamParms->node));
2302 ALOGV("DEBUG(%s): calling stream(%d) streamoff done", __FUNCTION__, selfThread->m_index);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002303 if (selfStreamParms->streamType == 0) {
2304 ALOGV("DEBUG(%s): calling stream(%d) reqbuf 0 (fd:%d)", __FUNCTION__,
2305 selfThread->m_index, selfStreamParms->fd);
2306 currentNode->buffers = 0;
2307 cam_int_reqbufs(currentNode);
2308 ALOGV("DEBUG(%s): calling stream(%d) reqbuf 0 DONE(fd:%d)", __FUNCTION__,
2309 selfThread->m_index, selfStreamParms->fd);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002310 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002311 selfThread->m_releasing = false;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002312 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002313 if (selfThread->m_index == 1 && m_resizeBuf.size.s != 0) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002314 freeCameraMemory(&m_resizeBuf, 1);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002315 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002316 selfThread->m_isBufferInit = false;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002317 selfThread->m_index = 255;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002318
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002319 ALOGV("DEBUG(%s): processing SIGNAL_THREAD_RELEASE DONE", __FUNCTION__);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002320
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002321 return;
2322 }
2323
2324 if (currentSignal & SIGNAL_STREAM_DATA_COMING) {
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002325 buffer_handle_t * buf = NULL;
2326 status_t res;
2327 void *virtAddr[3];
2328 int i, j;
2329 int index;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002330 ALOGV("DEBUG(%s): stream(%d) processing SIGNAL_STREAM_DATA_COMING",
2331 __FUNCTION__,selfThread->m_index);
2332 if (!(selfThread->m_isBufferInit)) {
2333 for ( i=0 ; i < selfStreamParms->numSvcBuffers; i++) {
2334 res = selfStreamParms->streamOps->dequeue_buffer(selfStreamParms->streamOps, &buf);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002335 if (res != NO_ERROR || buf == NULL) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002336 ALOGE("ERR(%s): Init: unable to dequeue buffer : %d",__FUNCTION__ , res);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002337 return;
2338 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002339 ALOGV("DEBUG(%s): got buf(%x) version(%d), numFds(%d), numInts(%d)", __FUNCTION__, (uint32_t)(*buf),
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002340 ((native_handle_t*)(*buf))->version, ((native_handle_t*)(*buf))->numFds, ((native_handle_t*)(*buf))->numInts);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002341
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002342 if (m_grallocHal->lock(m_grallocHal, *buf,
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002343 selfStreamParms->usage,
2344 0, 0, selfStreamParms->outputWidth, selfStreamParms->outputHeight, virtAddr) != 0) {
2345 ALOGE("ERR(%s): could not obtain gralloc buffer", __FUNCTION__);
2346 return;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002347 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002348 ALOGV("DEBUG(%s): locked img buf plane0(%x) plane1(%x) plane2(%x)",
2349 __FUNCTION__, (unsigned int)virtAddr[0], (unsigned int)virtAddr[1], (unsigned int)virtAddr[2]);
2350
2351 index = selfThread->findBufferIndex(virtAddr[0]);
2352 if (index == -1) {
2353 ALOGE("ERR(%s): could not find buffer index", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002354 }
2355 else {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002356 ALOGV("DEBUG(%s): found buffer index[%d] - status(%d)",
2357 __FUNCTION__, index, selfStreamParms->svcBufStatus[index]);
2358 if (selfStreamParms->svcBufStatus[index]== REQUIRES_DQ_FROM_SVC)
2359 selfStreamParms->svcBufStatus[index] = ON_DRIVER;
2360 else if (selfStreamParms->svcBufStatus[index]== ON_SERVICE)
2361 selfStreamParms->svcBufStatus[index] = ON_HAL;
2362 else {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002363 ALOGV("DBG(%s): buffer status abnormal (%d) "
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002364 , __FUNCTION__, selfStreamParms->svcBufStatus[index]);
2365 }
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002366 selfStreamParms->numSvcBufsInHal++;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002367 if (*buf != selfStreamParms->svcBufHandle[index])
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002368 ALOGV("DBG(%s): different buf_handle index ", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002369 else
2370 ALOGV("DEBUG(%s): same buf_handle index", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002371 }
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002372 selfStreamParms->svcBufIndex = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002373 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002374 selfThread->m_isBufferInit = true;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002375 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002376
2377 if (m_recordingEnabled && m_needsRecordBufferInit) {
2378 ALOGV("DEBUG(%s): Recording Buffer Initialization numsvcbuf(%d)",
2379 __FUNCTION__, selfRecordParms->numSvcBuffers);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002380 int checkingIndex = 0;
2381 bool found = false;
2382 for ( i=0 ; i < selfRecordParms->numSvcBuffers; i++) {
2383 res = selfRecordParms->streamOps->dequeue_buffer(selfRecordParms->streamOps, &buf);
2384 if (res != NO_ERROR || buf == NULL) {
2385 ALOGE("ERR(%s): Init: unable to dequeue buffer : %d",__FUNCTION__ , res);
2386 return;
2387 }
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002388 selfRecordParms->numSvcBufsInHal++;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002389 ALOGV("DEBUG(%s): [record] got buf(%x) bufInHal(%d) version(%d), numFds(%d), numInts(%d)", __FUNCTION__, (uint32_t)(*buf),
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002390 selfRecordParms->numSvcBufsInHal, ((native_handle_t*)(*buf))->version, ((native_handle_t*)(*buf))->numFds, ((native_handle_t*)(*buf))->numInts);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002391
2392 if (m_grallocHal->lock(m_grallocHal, *buf,
2393 selfRecordParms->usage, 0, 0,
2394 selfRecordParms->outputWidth, selfRecordParms->outputHeight, virtAddr) != 0) {
2395 ALOGE("ERR(%s): could not obtain gralloc buffer", __FUNCTION__);
2396 }
2397 else {
2398 ALOGV("DEBUG(%s): [record] locked img buf plane0(%x) plane1(%x) plane2(%x)",
2399 __FUNCTION__, (unsigned int)virtAddr[0], (unsigned int)virtAddr[1], (unsigned int)virtAddr[2]);
2400
2401 }
2402 found = false;
2403 for (checkingIndex = 0; checkingIndex < selfRecordParms->numSvcBuffers ; checkingIndex++) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002404 if (selfRecordParms->svcBufHandle[checkingIndex] == *buf ) {
2405 found = true;
2406 break;
2407 }
2408 }
2409 ALOGV("DEBUG(%s): [record] found(%d) - index[%d]", __FUNCTION__, found, checkingIndex);
2410 if (!found) break;
2411 index = checkingIndex;
2412
2413
2414 if (index == -1) {
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002415 ALOGD("ERR(%s): could not find buffer index", __FUNCTION__);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002416 }
2417 else {
2418 ALOGV("DEBUG(%s): found buffer index[%d] - status(%d)",
2419 __FUNCTION__, index, selfRecordParms->svcBufStatus[index]);
2420 if (selfRecordParms->svcBufStatus[index]== ON_SERVICE)
2421 selfRecordParms->svcBufStatus[index] = ON_HAL;
2422 else {
2423 ALOGV("DBG(%s): buffer status abnormal (%d) "
2424 , __FUNCTION__, selfRecordParms->svcBufStatus[index]);
2425 }
2426 if (*buf != selfRecordParms->svcBufHandle[index])
2427 ALOGV("DBG(%s): different buf_handle index ", __FUNCTION__);
2428 else
2429 ALOGV("DEBUG(%s): same buf_handle index", __FUNCTION__);
2430 }
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002431 selfRecordParms->svcBufIndex = 0;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002432 }
2433 m_needsRecordBufferInit = false;
2434 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002435
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002436 do {
2437 if (selfStreamParms->streamType == 0) {
2438 ALOGV("DEBUG(%s): stream(%d) type(%d) DQBUF START ",__FUNCTION__,
2439 selfThread->m_index, selfStreamParms->streamType);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002440
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002441 index = cam_int_dqbuf(&(selfStreamParms->node));
2442 ALOGV("DEBUG(%s): stream(%d) type(%d) DQBUF done index(%d)",__FUNCTION__,
2443 selfThread->m_index, selfStreamParms->streamType, index);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002444
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002445
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002446 if (selfStreamParms->svcBufStatus[index] != ON_DRIVER)
2447 ALOGD("DBG(%s): DQed buffer status abnormal (%d) ",
2448 __FUNCTION__, selfStreamParms->svcBufStatus[index]);
2449 selfStreamParms->svcBufStatus[index] = ON_HAL;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002450
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002451 if (m_recordOutput && m_recordingEnabled) {
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002452 ALOGV("DEBUG(%s): Entering record frame creator, index(%d)",__FUNCTION__, selfRecordParms->svcBufIndex);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002453 bool found = false;
2454 for (int i = 0 ; selfRecordParms->numSvcBuffers ; i++) {
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002455 if (selfRecordParms->svcBufStatus[selfRecordParms->svcBufIndex] == ON_HAL) {
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002456 found = true;
2457 break;
2458 }
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002459 selfRecordParms->svcBufIndex++;
2460 if (selfRecordParms->svcBufIndex >= selfRecordParms->numSvcBuffers)
2461 selfRecordParms->svcBufIndex = 0;
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002462 }
2463 if (!found) {
2464 ALOGE("(%s): cannot find free recording buffer", __FUNCTION__);
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002465 selfRecordParms->svcBufIndex++;
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002466 break;
2467 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002468
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002469 if (m_exynosVideoCSC) {
2470 int videoW = selfRecordParms->outputWidth, videoH = selfRecordParms->outputHeight;
2471 int cropX, cropY, cropW, cropH = 0;
2472 int previewW = selfStreamParms->outputWidth, previewH = selfStreamParms->outputHeight;
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002473 m_getRatioSize(previewW, previewH,
Sungjoong Kang804236a2012-08-05 10:36:19 -07002474 videoW, videoH,
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002475 &cropX, &cropY,
2476 &cropW, &cropH,
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002477 0);
2478
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002479 ALOGV("DEBUG(%s):cropX = %d, cropY = %d, cropW = %d, cropH = %d",
2480 __FUNCTION__, cropX, cropY, cropW, cropH);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002481
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002482 csc_set_src_format(m_exynosVideoCSC,
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002483 previewW, previewH,
2484 cropX, cropY, cropW, cropH,
2485 HAL_PIXEL_FORMAT_YV12,
2486 0);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002487
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002488 csc_set_dst_format(m_exynosVideoCSC,
Sungjoong Kang804236a2012-08-05 10:36:19 -07002489 videoW, videoH,
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002490 0, 0, videoW, videoH,
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002491 selfRecordParms->outputFormat,
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002492 1);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002493
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002494 csc_set_src_buffer(m_exynosVideoCSC,
2495 (void **)(&(selfStreamParms->svcBuffers[index].fd.fd)));
Sungjoong Kang804236a2012-08-05 10:36:19 -07002496
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002497 csc_set_dst_buffer(m_exynosVideoCSC,
Sungjoong Kang804236a2012-08-05 10:36:19 -07002498 (void **)(&(selfRecordParms->svcBuffers[selfRecordParms->svcBufIndex].fd.fd)));
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002499
2500 if (csc_convert(m_exynosVideoCSC) != 0) {
2501 ALOGE("ERR(%s):csc_convert() fail", __FUNCTION__);
2502 }
2503 else {
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002504 ALOGV("(%s):csc_convert() SUCCESS", __FUNCTION__);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002505 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002506 }
2507 else {
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002508 ALOGE("ERR(%s):m_exynosVideoCSC == NULL", __FUNCTION__);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002509 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002510
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002511 res = selfRecordParms->streamOps->enqueue_buffer(selfRecordParms->streamOps,
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002512 m_requestManager->GetTimestamp(m_ispProcessingFrameCnt),
2513 &(selfRecordParms->svcBufHandle[selfRecordParms->svcBufIndex]));
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002514 ALOGV("DEBUG(%s): stream(%d) record enqueue_buffer to svc done res(%d)", __FUNCTION__,
2515 selfThread->m_index, res);
2516 if (res == 0) {
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002517 selfRecordParms->svcBufStatus[selfRecordParms->svcBufIndex] = ON_SERVICE;
2518 selfRecordParms->numSvcBufsInHal--;
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002519 }
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002520
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002521 m_requestManager->NotifyStreamOutput(m_ispProcessingFrameCnt, 2);
2522
2523 }
2524 if (m_previewOutput) {
2525 res = selfStreamParms->streamOps->enqueue_buffer(selfStreamParms->streamOps,
2526 m_requestManager->GetTimestamp(m_ispProcessingFrameCnt), &(selfStreamParms->svcBufHandle[index]));
2527 ALOGV("DEBUG(%s): stream(%d) enqueue_buffer to svc done res(%d)", __FUNCTION__, selfThread->m_index, res);
2528 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002529 else {
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002530 res = selfStreamParms->streamOps->cancel_buffer(selfStreamParms->streamOps,
2531 &(selfStreamParms->svcBufHandle[index]));
2532 ALOGV("DEBUG(%s): stream(%d) cancel_buffer to svc done res(%d)", __FUNCTION__, selfThread->m_index, res);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002533 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002534 if (res == 0) {
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002535 selfStreamParms->svcBufStatus[index] = ON_SERVICE;
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002536 selfStreamParms->numSvcBufsInHal--;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002537 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002538 else {
2539 selfStreamParms->svcBufStatus[index] = ON_HAL;
2540 }
2541 m_requestManager->NotifyStreamOutput(m_ispProcessingFrameCnt, selfThread->m_index);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002542 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002543 else if (selfStreamParms->streamType == 1) {
2544 ALOGV("DEBUG(%s): stream(%d) type(%d) DQBUF START ",__FUNCTION__,
2545 selfThread->m_index, selfStreamParms->streamType);
2546 index = cam_int_dqbuf(&(selfStreamParms->node));
2547 ALOGV("DEBUG(%s): stream(%d) type(%d) DQBUF done index(%d)",__FUNCTION__,
2548 selfThread->m_index, selfStreamParms->streamType, index);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002549
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002550 m_jpegEncodingFrameCnt = m_ispProcessingFrameCnt;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002551
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002552 bool ret = false;
2553 int pictureW, pictureH, pictureFramesize = 0;
2554 int pictureFormat;
2555 int cropX, cropY, cropW, cropH = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002556
2557
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002558 ExynosBuffer jpegBuf, resizeBufInfo;
Rebecca Schultz Zavina8b0b072012-06-26 12:50:15 -07002559
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002560 ExynosRect m_orgPictureRect;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002561
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002562 m_orgPictureRect.w = selfStreamParms->outputWidth;
2563 m_orgPictureRect.h = selfStreamParms->outputHeight;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002564
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002565 ExynosBuffer* m_pictureBuf = &(m_camera_info.capture.buffer[index]);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002566
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07002567 pictureW = selfStreamParms->nodeWidth;
2568 pictureH = selfStreamParms->nodeHeight;
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002569 pictureFormat = V4L2_PIX_FMT_YUYV;
2570 pictureFramesize = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(pictureFormat), pictureW, pictureH);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002571
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002572 if (m_exynosPictureCSC) {
2573 m_getRatioSize(pictureW, pictureH,
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002574 m_orgPictureRect.w, m_orgPictureRect.h,
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002575 &cropX, &cropY,
2576 &cropW, &cropH,
2577 0);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002578
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002579 ALOGV("DEBUG(%s):cropX = %d, cropY = %d, cropW = %d, cropH = %d",
2580 __FUNCTION__, cropX, cropY, cropW, cropH);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002581
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002582 csc_set_src_format(m_exynosPictureCSC,
2583 ALIGN(pictureW, 16), ALIGN(pictureH, 16),
2584 cropX, cropY, cropW, cropH,
2585 V4L2_PIX_2_HAL_PIXEL_FORMAT(pictureFormat),
2586 0);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002587
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002588 csc_set_dst_format(m_exynosPictureCSC,
2589 m_orgPictureRect.w, m_orgPictureRect.h,
2590 0, 0, m_orgPictureRect.w, m_orgPictureRect.h,
2591 V4L2_PIX_2_HAL_PIXEL_FORMAT(V4L2_PIX_FMT_NV16),
2592 0);
2593 csc_set_src_buffer(m_exynosPictureCSC,
2594 (void **)&m_pictureBuf->fd.fd);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002595
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002596 csc_set_dst_buffer(m_exynosPictureCSC,
2597 (void **)&m_resizeBuf.fd.fd);
2598 for (int i=0 ; i < 3 ; i++)
2599 ALOGV("DEBUG(%s): m_resizeBuf.virt.extP[%d]=%d m_resizeBuf.size.extS[%d]=%d",
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002600 __FUNCTION__, i, m_resizeBuf.fd.extFd[i], i, m_resizeBuf.size.extS[i]);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002601
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002602 if (csc_convert(m_exynosPictureCSC) != 0)
2603 ALOGE("ERR(%s): csc_convert() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002604
2605
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002606 }
2607 else {
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002608 ALOGE("ERR(%s): m_exynosPictureCSC == NULL", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002609 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002610
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002611 resizeBufInfo = m_resizeBuf;
2612
2613 m_getAlignedYUVSize(V4L2_PIX_FMT_NV16, m_orgPictureRect.w, m_orgPictureRect.h, &m_resizeBuf);
2614
2615 for (int i = 1; i < 3; i++) {
2616 if (m_resizeBuf.size.extS[i] != 0)
2617 m_resizeBuf.fd.extFd[i] = m_resizeBuf.fd.extFd[i-1] + m_resizeBuf.size.extS[i-1];
2618
2619 ALOGV("(%s): m_resizeBuf.size.extS[%d] = %d", __FUNCTION__, i, m_resizeBuf.size.extS[i]);
2620 }
2621
2622
2623 ExynosRect jpegRect;
2624 bool found = false;
2625 jpegRect.w = m_orgPictureRect.w;
2626 jpegRect.h = m_orgPictureRect.h;
2627 jpegRect.colorFormat = V4L2_PIX_FMT_NV16;
2628
2629 jpegBuf.size.extS[0] = 5*1024*1024;
2630 jpegBuf.size.extS[1] = 0;
2631 jpegBuf.size.extS[2] = 0;
2632
2633 allocCameraMemory(currentNode->ionClient, &jpegBuf, 1);
2634
2635 ALOGV("DEBUG(%s): jpegBuf.size.s = %d , jpegBuf.virt.p = %x", __FUNCTION__,
2636 jpegBuf.size.s, (unsigned int)jpegBuf.virt.p);
2637
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002638 m_requestManager->NotifyStreamOutput(m_jpegEncodingFrameCnt, selfThread->m_index);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002639 if (yuv2Jpeg(&m_resizeBuf, &jpegBuf, &jpegRect) == false)
2640 ALOGE("ERR(%s):yuv2Jpeg() fail", __FUNCTION__);
2641 cam_int_qbuf(&(selfStreamParms->node), index);
2642 ALOGV("DEBUG(%s): stream(%d) type(%d) QBUF DONE ",__FUNCTION__,
2643 selfThread->m_index, selfStreamParms->streamType);
2644
2645 m_resizeBuf = resizeBufInfo;
2646
2647 for (int i = 0; i < selfStreamParms->numSvcBuffers ; i++) {
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002648 if (selfStreamParms->svcBufStatus[selfStreamParms->svcBufIndex] == ON_HAL) {
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002649 found = true;
2650 break;
2651 }
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002652 selfStreamParms->svcBufIndex++;
2653 if (selfStreamParms->svcBufIndex >= selfStreamParms->numSvcBuffers)
2654 selfStreamParms->svcBufIndex = 0;
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002655 }
2656 if (!found) {
2657 ALOGE("ERR(%s): NO free SVC buffer for JPEG", __FUNCTION__);
2658 }
2659 else {
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002660 memcpy(selfStreamParms->svcBuffers[selfStreamParms->svcBufIndex].virt.extP[0], jpegBuf.virt.extP[0], 5*1024*1024);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002661
2662 res = selfStreamParms->streamOps->enqueue_buffer(selfStreamParms->streamOps,
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002663 m_requestManager->GetTimestamp(m_jpegEncodingFrameCnt), &(selfStreamParms->svcBufHandle[selfStreamParms->svcBufIndex]));
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002664
2665 freeCameraMemory(&jpegBuf, 1);
2666 ALOGV("DEBUG(%s): stream(%d) enqueue_buffer index(%d) to svc done res(%d)",
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002667 __FUNCTION__, selfThread->m_index, selfStreamParms->svcBufIndex, res);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002668 if (res == 0) {
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002669 selfStreamParms->svcBufStatus[selfStreamParms->svcBufIndex] = ON_SERVICE;
2670 selfStreamParms->numSvcBufsInHal--;
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002671 }
2672 else {
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002673 selfStreamParms->svcBufStatus[selfStreamParms->svcBufIndex] = ON_HAL;
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002674 }
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002675
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002676 }
2677
2678 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002679 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002680 while (0);
2681
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002682 if (selfStreamParms->streamType==0 && m_recordOutput && m_recordingEnabled) {
2683 do {
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002684 ALOGV("DEBUG(%s): record currentBuf#(%d)", __FUNCTION__ , selfRecordParms->numSvcBufsInHal);
2685 if (selfRecordParms->numSvcBufsInHal >= 1)
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002686 {
2687 ALOGV("DEBUG(%s): breaking", __FUNCTION__);
2688 break;
2689 }
2690 res = selfRecordParms->streamOps->dequeue_buffer(selfRecordParms->streamOps, &buf);
2691 if (res != NO_ERROR || buf == NULL) {
2692 ALOGV("DEBUG(%s): record stream(%d) dequeue_buffer fail res(%d)",__FUNCTION__ , selfThread->m_index, res);
2693 break;
2694 }
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002695 selfRecordParms->numSvcBufsInHal ++;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002696 ALOGV("DEBUG(%s): record got buf(%x) numBufInHal(%d) version(%d), numFds(%d), numInts(%d)", __FUNCTION__, (uint32_t)(*buf),
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002697 selfRecordParms->numSvcBufsInHal, ((native_handle_t*)(*buf))->version, ((native_handle_t*)(*buf))->numFds, ((native_handle_t*)(*buf))->numInts);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002698 const private_handle_t *priv_handle = reinterpret_cast<const private_handle_t *>(*buf);
2699
2700 bool found = false;
2701 int checkingIndex = 0;
2702 for (checkingIndex = 0; checkingIndex < selfRecordParms->numSvcBuffers ; checkingIndex++) {
2703 if (priv_handle->fd == selfRecordParms->svcBuffers[checkingIndex].fd.extFd[0] ) {
2704 found = true;
2705 break;
2706 }
2707 }
2708 ALOGV("DEBUG(%s): recording dequeueed_buffer found index(%d)", __FUNCTION__, found);
2709 if (!found) break;
2710 index = checkingIndex;
2711 if (selfRecordParms->svcBufStatus[index] == ON_SERVICE) {
2712 selfRecordParms->svcBufStatus[index] = ON_HAL;
2713 }
2714 else {
2715 ALOGV("DEBUG(%s): record bufstatus abnormal [%d] status = %d", __FUNCTION__,
2716 index, selfRecordParms->svcBufStatus[index]);
2717 }
2718 } while (0);
2719 }
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002720 if (selfStreamParms->streamType == 0) {
2721 while (selfStreamParms->numSvcBufsInHal < selfStreamParms->numOwnSvcBuffers) {
2722 res = selfStreamParms->streamOps->dequeue_buffer(selfStreamParms->streamOps, &buf);
2723 if (res != NO_ERROR || buf == NULL) {
2724 ALOGV("DEBUG(%s): stream(%d) dequeue_buffer fail res(%d)",__FUNCTION__ , selfThread->m_index, res);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002725 break;
2726 }
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002727 selfStreamParms->numSvcBufsInHal++;
2728 ALOGV("DEBUG(%s): stream(%d) got buf(%x) numInHal(%d) version(%d), numFds(%d), numInts(%d)", __FUNCTION__,
2729 selfThread->m_index, (uint32_t)(*buf), selfStreamParms->numSvcBufsInHal,
2730 ((native_handle_t*)(*buf))->version, ((native_handle_t*)(*buf))->numFds, ((native_handle_t*)(*buf))->numInts);
2731 const private_handle_t *priv_handle = reinterpret_cast<const private_handle_t *>(*buf);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002732
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002733 bool found = false;
2734 int checkingIndex = 0;
2735 for (checkingIndex = 0; checkingIndex < selfStreamParms->numSvcBuffers ; checkingIndex++) {
2736 if (priv_handle->fd == selfStreamParms->svcBuffers[checkingIndex].fd.extFd[0] ) {
2737 found = true;
2738 break;
2739 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002740 }
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002741 ALOGV("DEBUG(%s): post_dequeue_buffer found(%d)", __FUNCTION__, found);
2742 if (!found) break;
2743 ALOGV("DEBUG(%s): preparing to qbuf [%d]", __FUNCTION__, checkingIndex);
2744 index = checkingIndex;
2745 if (index < selfStreamParms->numHwBuffers) {
2746 uint32_t plane_index = 0;
2747 ExynosBuffer* currentBuf = &(selfStreamParms->svcBuffers[index]);
2748 struct v4l2_buffer v4l2_buf;
2749 struct v4l2_plane planes[VIDEO_MAX_PLANES];
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002750
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002751 v4l2_buf.m.planes = planes;
2752 v4l2_buf.type = currentNode->type;
2753 v4l2_buf.memory = currentNode->memory;
2754 v4l2_buf.index = index;
2755 v4l2_buf.length = currentNode->planes;
2756
2757 v4l2_buf.m.planes[0].m.fd = priv_handle->fd;
2758 v4l2_buf.m.planes[2].m.fd = priv_handle->fd1;
2759 v4l2_buf.m.planes[1].m.fd = priv_handle->fd2;
2760 for (plane_index=0 ; plane_index < v4l2_buf.length ; plane_index++) {
2761 v4l2_buf.m.planes[plane_index].length = currentBuf->size.extS[plane_index];
2762 ALOGV("DEBUG(%s): plane(%d): fd(%d) length(%d)",
2763 __FUNCTION__, plane_index, v4l2_buf.m.planes[plane_index].m.fd,
2764 v4l2_buf.m.planes[plane_index].length);
2765 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002766 if (exynos_v4l2_qbuf(currentNode->fd, &v4l2_buf) < 0) {
2767 ALOGE("ERR(%s): stream id(%d) exynos_v4l2_qbuf() fail",
2768 __FUNCTION__, selfThread->m_index);
2769 return;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002770 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002771 selfStreamParms->svcBufStatus[index] = ON_DRIVER;
2772 ALOGV("DEBUG(%s): stream id(%d) type0 QBUF done index(%d)",
2773 __FUNCTION__, selfThread->m_index, index);
2774 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002775 }
2776 }
Sungjoong Kangbe494d12012-08-04 15:36:56 -07002777 else if (selfStreamParms->streamType == 1) {
2778 while (selfStreamParms->numSvcBufsInHal < selfStreamParms->numOwnSvcBuffers) {
2779 res = selfStreamParms->streamOps->dequeue_buffer(selfStreamParms->streamOps, &buf);
2780 if (res != NO_ERROR || buf == NULL) {
2781 ALOGV("DEBUG(%s): stream(%d) dequeue_buffer fail res(%d)",__FUNCTION__ , selfThread->m_index, res);
2782 break;
2783 }
2784
2785 ALOGV("DEBUG(%s): stream(%d) got buf(%x) numInHal(%d) version(%d), numFds(%d), numInts(%d)", __FUNCTION__,
2786 selfThread->m_index, (uint32_t)(*buf), selfStreamParms->numSvcBufsInHal,
2787 ((native_handle_t*)(*buf))->version, ((native_handle_t*)(*buf))->numFds, ((native_handle_t*)(*buf))->numInts);
2788
2789 const private_handle_t *priv_handle = reinterpret_cast<const private_handle_t *>(*buf);
2790
2791 bool found = false;
2792 int checkingIndex = 0;
2793 for (checkingIndex = 0; checkingIndex < selfStreamParms->numSvcBuffers ; checkingIndex++) {
2794 if (priv_handle->fd == selfStreamParms->svcBuffers[checkingIndex].fd.extFd[0] ) {
2795 found = true;
2796 break;
2797 }
2798 }
2799 if (!found) break;
2800 selfStreamParms->svcBufStatus[checkingIndex] = ON_HAL;
2801 selfStreamParms->numSvcBufsInHal++;
2802 }
2803
2804 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002805 ALOGV("DEBUG(%s): stream(%d) processing SIGNAL_STREAM_DATA_COMING DONE",
2806 __FUNCTION__,selfThread->m_index);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002807 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002808 return;
2809}
2810
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002811bool ExynosCameraHWInterface2::yuv2Jpeg(ExynosBuffer *yuvBuf,
2812 ExynosBuffer *jpegBuf,
2813 ExynosRect *rect)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002814{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002815 unsigned char *addr;
2816
2817 ExynosJpegEncoderForCamera jpegEnc;
2818 bool ret = false;
2819 int res = 0;
2820
2821 unsigned int *yuvSize = yuvBuf->size.extS;
2822
2823 if (jpegEnc.create()) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002824 ALOGE("ERR(%s):jpegEnc.create() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002825 goto jpeg_encode_done;
2826 }
2827
2828 if (jpegEnc.setQuality(100)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002829 ALOGE("ERR(%s):jpegEnc.setQuality() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002830 goto jpeg_encode_done;
2831 }
2832
2833 if (jpegEnc.setSize(rect->w, rect->h)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002834 ALOGE("ERR(%s):jpegEnc.setSize() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002835 goto jpeg_encode_done;
2836 }
2837 ALOGV("%s : width = %d , height = %d\n", __FUNCTION__, rect->w, rect->h);
2838
2839 if (jpegEnc.setColorFormat(rect->colorFormat)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002840 ALOGE("ERR(%s):jpegEnc.setColorFormat() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002841 goto jpeg_encode_done;
2842 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002843
2844 if (jpegEnc.setJpegFormat(V4L2_PIX_FMT_JPEG_422)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002845 ALOGE("ERR(%s):jpegEnc.setJpegFormat() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002846 goto jpeg_encode_done;
2847 }
2848#if 0
2849 if (m_curCameraInfo->thumbnailW != 0 && m_curCameraInfo->thumbnailH != 0) {
2850 int thumbW = 0, thumbH = 0;
2851 mExifInfo.enableThumb = true;
2852 if (rect->w < 320 || rect->h < 240) {
2853 thumbW = 160;
2854 thumbH = 120;
2855 } else {
2856 thumbW = m_curCameraInfo->thumbnailW;
2857 thumbH = m_curCameraInfo->thumbnailH;
2858 }
2859 if (jpegEnc.setThumbnailSize(thumbW, thumbH)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002860 LOGE("ERR(%s):jpegEnc.setThumbnailSize(%d, %d) fail", __FUNCTION__, thumbW, thumbH);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002861 goto jpeg_encode_done;
2862 }
2863
2864 if (0 < m_jpegThumbnailQuality && m_jpegThumbnailQuality <= 100) {
2865 if (jpegEnc.setThumbnailQuality(m_jpegThumbnailQuality)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002866 LOGE("ERR(%s):jpegEnc.setThumbnailQuality(%d) fail", __FUNCTION__, m_jpegThumbnailQuality);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002867 goto jpeg_encode_done;
2868 }
2869 }
2870
2871 m_setExifChangedAttribute(&mExifInfo, rect);
2872 } else
2873#endif
2874 {
2875 mExifInfo.enableThumb = false;
2876 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002877 ALOGV("DEBUG(%s):calling jpegEnc.setInBuf() yuvSize(%d)", __FUNCTION__, *yuvSize);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002878 if (jpegEnc.setInBuf((int *)&(yuvBuf->fd.fd), (int *)yuvSize)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002879 ALOGE("ERR(%s):jpegEnc.setInBuf() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002880 goto jpeg_encode_done;
2881 }
2882
2883 if (jpegEnc.setOutBuf(jpegBuf->fd.fd, jpegBuf->size.extS[0] + jpegBuf->size.extS[1] + jpegBuf->size.extS[2])) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002884 ALOGE("ERR(%s):jpegEnc.setOutBuf() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002885 goto jpeg_encode_done;
2886 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002887 memset(jpegBuf->virt.p,0,jpegBuf->size.extS[0] + jpegBuf->size.extS[1] + jpegBuf->size.extS[2]);
2888
2889 if (jpegEnc.updateConfig()) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002890 ALOGE("ERR(%s):jpegEnc.updateConfig() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002891 goto jpeg_encode_done;
2892 }
2893
2894 if (res = jpegEnc.encode((int *)&jpegBuf->size.s, NULL)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002895 ALOGE("ERR(%s):jpegEnc.encode() fail ret(%d)", __FUNCTION__, res);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002896 goto jpeg_encode_done;
2897 }
2898
2899 ret = true;
2900
2901jpeg_encode_done:
2902
2903 if (jpegEnc.flagCreate() == true)
2904 jpegEnc.destroy();
2905
2906 return ret;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002907}
2908
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002909
2910ExynosCameraHWInterface2::MainThread::~MainThread()
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002911{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002912 ALOGD("(%s):", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002913}
2914
2915void ExynosCameraHWInterface2::MainThread::release()
2916{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002917 ALOGD("(%s):", __func__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002918 SetSignal(SIGNAL_THREAD_RELEASE);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002919}
2920
2921ExynosCameraHWInterface2::SensorThread::~SensorThread()
2922{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002923 ALOGD("(%s):", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002924}
2925
2926void ExynosCameraHWInterface2::SensorThread::release()
2927{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002928 ALOGD("(%s):", __func__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002929 SetSignal(SIGNAL_THREAD_RELEASE);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002930}
2931
2932ExynosCameraHWInterface2::IspThread::~IspThread()
2933{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002934 ALOGD("(%s):", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002935}
2936
2937void ExynosCameraHWInterface2::IspThread::release()
2938{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002939 ALOGD("(%s):", __func__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002940 SetSignal(SIGNAL_THREAD_RELEASE);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002941}
2942
2943ExynosCameraHWInterface2::StreamThread::~StreamThread()
2944{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002945 ALOGD("(%s):", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002946}
2947
2948void ExynosCameraHWInterface2::StreamThread::setParameter(stream_parameters_t * new_parameters)
2949{
2950 ALOGV("DEBUG(%s):", __FUNCTION__);
2951
2952 m_tempParameters = new_parameters;
2953
2954 SetSignal(SIGNAL_STREAM_CHANGE_PARAMETER);
2955
2956 // TODO : return synchronously (after setting parameters asynchronously)
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002957 usleep(2000);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002958}
2959
2960void ExynosCameraHWInterface2::StreamThread::applyChange()
2961{
2962 memcpy(&m_parameters, m_tempParameters, sizeof(stream_parameters_t));
2963
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002964 ALOGV("DEBUG(%s): Applying Stream paremeters width(%d), height(%d)",
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002965 __FUNCTION__, m_parameters.outputWidth, m_parameters.outputHeight);
2966}
2967
2968void ExynosCameraHWInterface2::StreamThread::release()
2969{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002970 ALOGV("(%s):", __func__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002971 SetSignal(SIGNAL_THREAD_RELEASE);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002972}
2973
2974int ExynosCameraHWInterface2::StreamThread::findBufferIndex(void * bufAddr)
2975{
2976 int index;
2977 for (index = 0 ; index < m_parameters.numSvcBuffers ; index++) {
2978 if (m_parameters.svcBuffers[index].virt.extP[0] == bufAddr)
2979 return index;
2980 }
2981 return -1;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002982}
2983
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002984void ExynosCameraHWInterface2::StreamThread::setRecordingParameter(record_parameters_t * recordParm)
2985{
2986 memcpy(&m_recordParameters, recordParm, sizeof(record_parameters_t));
2987}
2988
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002989int ExynosCameraHWInterface2::createIonClient(ion_client ionClient)
2990{
2991 if (ionClient == 0) {
2992 ionClient = ion_client_create();
2993 if (ionClient < 0) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002994 ALOGE("[%s]src ion client create failed, value = %d\n", __FUNCTION__, ionClient);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002995 return 0;
2996 }
2997 }
2998
2999 return ionClient;
3000}
3001
3002int ExynosCameraHWInterface2::deleteIonClient(ion_client ionClient)
3003{
3004 if (ionClient != 0) {
3005 if (ionClient > 0) {
3006 ion_client_destroy(ionClient);
3007 }
3008 ionClient = 0;
3009 }
3010
3011 return ionClient;
3012}
3013
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003014int ExynosCameraHWInterface2::allocCameraMemory(ion_client ionClient, ExynosBuffer *buf, int iMemoryNum)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003015{
3016 int ret = 0;
3017 int i = 0;
3018
3019 if (ionClient == 0) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003020 ALOGE("[%s] ionClient is zero (%d)\n", __FUNCTION__, ionClient);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003021 return -1;
3022 }
3023
3024 for (i=0;i<iMemoryNum;i++) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003025 if (buf->size.extS[i] == 0) {
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003026 break;
3027 }
3028
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003029 buf->fd.extFd[i] = ion_alloc(ionClient, \
3030 buf->size.extS[i], 0, ION_HEAP_EXYNOS_MASK,0);
3031 if ((buf->fd.extFd[i] == -1) ||(buf->fd.extFd[i] == 0)) {
3032 ALOGE("[%s]ion_alloc(%d) failed\n", __FUNCTION__, buf->size.extS[i]);
3033 buf->fd.extFd[i] = -1;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003034 freeCameraMemory(buf, iMemoryNum);
3035 return -1;
3036 }
3037
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003038 buf->virt.extP[i] = (char *)ion_map(buf->fd.extFd[i], \
3039 buf->size.extS[i], 0);
3040 if ((buf->virt.extP[i] == (char *)MAP_FAILED) || (buf->virt.extP[i] == NULL)) {
3041 ALOGE("[%s]src ion map failed(%d)\n", __FUNCTION__, buf->size.extS[i]);
3042 buf->virt.extP[i] = (char *)MAP_FAILED;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003043 freeCameraMemory(buf, iMemoryNum);
3044 return -1;
3045 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003046 ALOGV("allocCameraMem : [%d][0x%08x] size(%d)", i, (unsigned int)(buf->virt.extP[i]), buf->size.extS[i]);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003047 }
3048
3049 return ret;
3050}
3051
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003052void ExynosCameraHWInterface2::freeCameraMemory(ExynosBuffer *buf, int iMemoryNum)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003053{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003054
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003055 int i =0 ;
3056
3057 for (i=0;i<iMemoryNum;i++) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003058 if (buf->fd.extFd[i] != -1) {
3059 if (buf->virt.extP[i] != (char *)MAP_FAILED) {
3060 ion_unmap(buf->virt.extP[i], buf->size.extS[i]);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003061 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003062 ion_free(buf->fd.extFd[i]);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003063 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003064 buf->fd.extFd[i] = -1;
3065 buf->virt.extP[i] = (char *)MAP_FAILED;
3066 buf->size.extS[i] = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003067 }
3068}
3069
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003070void ExynosCameraHWInterface2::initCameraMemory(ExynosBuffer *buf, int iMemoryNum)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003071{
3072 int i =0 ;
3073 for (i=0;i<iMemoryNum;i++) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003074 buf->virt.extP[i] = (char *)MAP_FAILED;
3075 buf->fd.extFd[i] = -1;
3076 buf->size.extS[i] = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003077 }
3078}
3079
3080
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003081
3082
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003083static camera2_device_t *g_cam2_device = NULL;
Sungjoong Kangb5237e62012-07-27 07:39:05 -07003084static bool g_camera_vaild = false;
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07003085ExynosCamera2 * g_camera2[2] = { NULL, NULL };
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003086
3087static int HAL2_camera_device_close(struct hw_device_t* device)
3088{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003089 ALOGD("%s: ENTER", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003090 if (device) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003091
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003092 camera2_device_t *cam_device = (camera2_device_t *)device;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003093 ALOGD("cam_device(0x%08x):", (unsigned int)cam_device);
3094 ALOGD("g_cam2_device(0x%08x):", (unsigned int)g_cam2_device);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003095 delete static_cast<ExynosCameraHWInterface2 *>(cam_device->priv);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003096 g_cam2_device = NULL;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003097 free(cam_device);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07003098 g_camera_vaild = false;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003099 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003100 ALOGD("%s: EXIT", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003101 return 0;
3102}
3103
3104static inline ExynosCameraHWInterface2 *obj(const struct camera2_device *dev)
3105{
3106 return reinterpret_cast<ExynosCameraHWInterface2 *>(dev->priv);
3107}
3108
3109static int HAL2_device_set_request_queue_src_ops(const struct camera2_device *dev,
3110 const camera2_request_queue_src_ops_t *request_src_ops)
3111{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003112 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003113 return obj(dev)->setRequestQueueSrcOps(request_src_ops);
3114}
3115
3116static int HAL2_device_notify_request_queue_not_empty(const struct camera2_device *dev)
3117{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003118 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003119 return obj(dev)->notifyRequestQueueNotEmpty();
3120}
3121
3122static int HAL2_device_set_frame_queue_dst_ops(const struct camera2_device *dev,
3123 const camera2_frame_queue_dst_ops_t *frame_dst_ops)
3124{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003125 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003126 return obj(dev)->setFrameQueueDstOps(frame_dst_ops);
3127}
3128
3129static int HAL2_device_get_in_progress_count(const struct camera2_device *dev)
3130{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003131 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003132 return obj(dev)->getInProgressCount();
3133}
3134
3135static int HAL2_device_flush_captures_in_progress(const struct camera2_device *dev)
3136{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003137 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003138 return obj(dev)->flushCapturesInProgress();
3139}
3140
3141static int HAL2_device_construct_default_request(const struct camera2_device *dev,
3142 int request_template, camera_metadata_t **request)
3143{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003144 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003145 return obj(dev)->constructDefaultRequest(request_template, request);
3146}
3147
3148static int HAL2_device_allocate_stream(
3149 const struct camera2_device *dev,
3150 // inputs
3151 uint32_t width,
3152 uint32_t height,
3153 int format,
3154 const camera2_stream_ops_t *stream_ops,
3155 // outputs
3156 uint32_t *stream_id,
3157 uint32_t *format_actual,
3158 uint32_t *usage,
3159 uint32_t *max_buffers)
3160{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003161 ALOGV("(%s): ", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003162 return obj(dev)->allocateStream(width, height, format, stream_ops,
3163 stream_id, format_actual, usage, max_buffers);
3164}
3165
3166
3167static int HAL2_device_register_stream_buffers(const struct camera2_device *dev,
3168 uint32_t stream_id,
3169 int num_buffers,
3170 buffer_handle_t *buffers)
3171{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003172 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003173 return obj(dev)->registerStreamBuffers(stream_id, num_buffers, buffers);
3174}
3175
3176static int HAL2_device_release_stream(
3177 const struct camera2_device *dev,
3178 uint32_t stream_id)
3179{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003180 ALOGD("DEBUG(%s)(id: %d):", __FUNCTION__, stream_id);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07003181 if (!g_camera_vaild)
3182 return 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003183 return obj(dev)->releaseStream(stream_id);
3184}
3185
3186static int HAL2_device_allocate_reprocess_stream(
3187 const struct camera2_device *dev,
3188 uint32_t width,
3189 uint32_t height,
3190 uint32_t format,
3191 const camera2_stream_in_ops_t *reprocess_stream_ops,
3192 // outputs
3193 uint32_t *stream_id,
3194 uint32_t *consumer_usage,
3195 uint32_t *max_buffers)
3196{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003197 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003198 return obj(dev)->allocateReprocessStream(width, height, format, reprocess_stream_ops,
3199 stream_id, consumer_usage, max_buffers);
3200}
3201
3202static int HAL2_device_release_reprocess_stream(
3203 const struct camera2_device *dev,
3204 uint32_t stream_id)
3205{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003206 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003207 return obj(dev)->releaseReprocessStream(stream_id);
3208}
3209
3210static int HAL2_device_trigger_action(const struct camera2_device *dev,
3211 uint32_t trigger_id,
3212 int ext1,
3213 int ext2)
3214{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003215 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003216 return obj(dev)->triggerAction(trigger_id, ext1, ext2);
3217}
3218
3219static int HAL2_device_set_notify_callback(const struct camera2_device *dev,
3220 camera2_notify_callback notify_cb,
3221 void *user)
3222{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003223 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003224 return obj(dev)->setNotifyCallback(notify_cb, user);
3225}
3226
3227static int HAL2_device_get_metadata_vendor_tag_ops(const struct camera2_device*dev,
3228 vendor_tag_query_ops_t **ops)
3229{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003230 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003231 return obj(dev)->getMetadataVendorTagOps(ops);
3232}
3233
3234static int HAL2_device_dump(const struct camera2_device *dev, int fd)
3235{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003236 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003237 return obj(dev)->dump(fd);
3238}
3239
3240
3241
3242
3243
3244static int HAL2_getNumberOfCameras()
3245{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003246 ALOGV("(%s): returning 2", __FUNCTION__);
3247 return 2;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003248}
3249
3250
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003251static int HAL2_getCameraInfo(int cameraId, struct camera_info *info)
3252{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003253 ALOGD("DEBUG(%s): cameraID: %d", __FUNCTION__, cameraId);
3254 static camera_metadata_t * mCameraInfo[2] = {NULL, NULL};
3255
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003256 status_t res;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003257
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07003258 if (cameraId == 0) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003259 info->facing = CAMERA_FACING_BACK;
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07003260 if (!g_camera2[0])
3261 g_camera2[0] = new ExynosCamera2(0);
3262 }
3263 else if (cameraId == 1) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003264 info->facing = CAMERA_FACING_FRONT;
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07003265 if (!g_camera2[1])
3266 g_camera2[1] = new ExynosCamera2(1);
3267 }
3268 else
3269 return BAD_VALUE;
3270
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003271 info->orientation = 0;
3272 info->device_version = HARDWARE_DEVICE_API_VERSION(2, 0);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003273 if (mCameraInfo[cameraId] == NULL) {
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07003274 res = g_camera2[cameraId]->constructStaticInfo(&(mCameraInfo[cameraId]), cameraId, true);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003275 if (res != OK) {
3276 ALOGE("%s: Unable to allocate static info: %s (%d)",
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003277 __FUNCTION__, strerror(-res), res);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003278 return res;
3279 }
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07003280 res = g_camera2[cameraId]->constructStaticInfo(&(mCameraInfo[cameraId]), cameraId, false);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003281 if (res != OK) {
3282 ALOGE("%s: Unable to fill in static info: %s (%d)",
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003283 __FUNCTION__, strerror(-res), res);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003284 return res;
3285 }
3286 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003287 info->static_camera_characteristics = mCameraInfo[cameraId];
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003288 return NO_ERROR;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003289}
3290
3291#define SET_METHOD(m) m : HAL2_device_##m
3292
3293static camera2_device_ops_t camera2_device_ops = {
3294 SET_METHOD(set_request_queue_src_ops),
3295 SET_METHOD(notify_request_queue_not_empty),
3296 SET_METHOD(set_frame_queue_dst_ops),
3297 SET_METHOD(get_in_progress_count),
3298 SET_METHOD(flush_captures_in_progress),
3299 SET_METHOD(construct_default_request),
3300 SET_METHOD(allocate_stream),
3301 SET_METHOD(register_stream_buffers),
3302 SET_METHOD(release_stream),
3303 SET_METHOD(allocate_reprocess_stream),
3304 SET_METHOD(release_reprocess_stream),
3305 SET_METHOD(trigger_action),
3306 SET_METHOD(set_notify_callback),
3307 SET_METHOD(get_metadata_vendor_tag_ops),
3308 SET_METHOD(dump),
3309};
3310
3311#undef SET_METHOD
3312
3313
3314static int HAL2_camera_device_open(const struct hw_module_t* module,
3315 const char *id,
3316 struct hw_device_t** device)
3317{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003318
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003319
3320 int cameraId = atoi(id);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003321
Sungjoong Kangb5237e62012-07-27 07:39:05 -07003322 g_camera_vaild = false;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003323 ALOGD("\n\n>>> I'm Samsung's CameraHAL_2(ID:%d) <<<\n\n", cameraId);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003324 if (cameraId < 0 || cameraId >= HAL2_getNumberOfCameras()) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003325 ALOGE("ERR(%s):Invalid camera ID %s", __FUNCTION__, id);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003326 return -EINVAL;
3327 }
3328
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003329 ALOGD("g_cam2_device : 0x%08x", (unsigned int)g_cam2_device);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003330 if (g_cam2_device) {
3331 if (obj(g_cam2_device)->getCameraId() == cameraId) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003332 ALOGV("DEBUG(%s):returning existing camera ID %s", __FUNCTION__, id);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003333 goto done;
3334 } else {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003335
3336 while (g_cam2_device)
3337 usleep(10000);
3338 /*ALOGE("ERR(%s):Cannot open camera %d. camera %d is already running!",
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003339 __FUNCTION__, cameraId, obj(g_cam2_device)->getCameraId());
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003340 return -ENOSYS;*/
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003341 }
3342 }
3343
3344 g_cam2_device = (camera2_device_t *)malloc(sizeof(camera2_device_t));
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003345 ALOGD("g_cam2_device : 0x%08x", (unsigned int)g_cam2_device);
3346
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003347 if (!g_cam2_device)
3348 return -ENOMEM;
3349
3350 g_cam2_device->common.tag = HARDWARE_DEVICE_TAG;
3351 g_cam2_device->common.version = CAMERA_DEVICE_API_VERSION_2_0;
3352 g_cam2_device->common.module = const_cast<hw_module_t *>(module);
3353 g_cam2_device->common.close = HAL2_camera_device_close;
3354
3355 g_cam2_device->ops = &camera2_device_ops;
3356
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003357 ALOGV("DEBUG(%s):open camera2 %s", __FUNCTION__, id);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003358
Sungjoong Kangdaa1fcd2012-08-08 11:49:43 -07003359 g_cam2_device->priv = new ExynosCameraHWInterface2(cameraId, g_cam2_device, g_camera2[cameraId]);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003360
3361done:
3362 *device = (hw_device_t *)g_cam2_device;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003363 ALOGV("DEBUG(%s):opened camera2 %s (%p)", __FUNCTION__, id, *device);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07003364 g_camera_vaild = true;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003365
3366 return 0;
3367}
3368
3369
3370static hw_module_methods_t camera_module_methods = {
3371 open : HAL2_camera_device_open
3372};
3373
3374extern "C" {
3375 struct camera_module HAL_MODULE_INFO_SYM = {
3376 common : {
3377 tag : HARDWARE_MODULE_TAG,
3378 module_api_version : CAMERA_MODULE_API_VERSION_2_0,
3379 hal_api_version : HARDWARE_HAL_API_VERSION,
3380 id : CAMERA_HARDWARE_MODULE_ID,
3381 name : "Exynos Camera HAL2",
3382 author : "Samsung Corporation",
3383 methods : &camera_module_methods,
3384 dso: NULL,
3385 reserved: {0},
3386 },
3387 get_number_of_cameras : HAL2_getNumberOfCameras,
3388 get_camera_info : HAL2_getCameraInfo
3389 };
3390}
3391
3392}; // namespace android