blob: b0b1a0ad07fcb40b91dc276ca647bcdce1d6e8df [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 Kang13d8c7b2012-07-14 10:20:39 +090046// temporarily copied from EmulatedFakeCamera2
47// TODO : implement our own codes
48status_t constructDefaultRequestInternal(
49 int request_template,
50 camera_metadata_t **request,
51 bool sizeRequest);
52
53status_t constructStaticInfo(
54 camera_metadata_t **info,
Sungjoong Kang9dd63e12012-07-24 00:25:51 +090055 int cameraId,
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +090056 bool sizeRequest);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -070057
Sungjoong Kang9dd63e12012-07-24 00:25:51 +090058bool isSupportedPreviewSize(int m_cameraId, int width, int height);
59bool isSupportedJpegSize(int m_cameraId, int width, int height);
60int getSccOutputSizeX(int cameraId);
61int getSccOutputSizeY(int cameraId);
62int getSensorOutputSizeX(int cameraId);
63int getSensorOutputSizeY(int cameraId);
64int getJpegOutputSizeX(int cameraId);
65int getJpegOutputSizeY(int cameraId);
66
67void m_savePostView(const char *fname, uint8_t *buf, uint32_t size)
68{
69 int nw;
70 int cnt = 0;
71 uint32_t written = 0;
72
73 ALOGD("opening file [%s], address[%x], size(%d)", fname, (unsigned int)buf, size);
74 int fd = open(fname, O_RDWR | O_CREAT, 0644);
75 if (fd < 0) {
76 ALOGE("failed to create file [%s]: %s", fname, strerror(errno));
77 return;
78 }
79
80 ALOGD("writing %d bytes to file [%s]", size, fname);
81 while (written < size) {
82 nw = ::write(fd, buf + written, size - written);
83 if (nw < 0) {
84 ALOGE("failed to write to file %d [%s]: %s",written,fname, strerror(errno));
85 break;
86 }
87 written += nw;
88 cnt++;
89 }
90 ALOGD("done writing %d bytes to file [%s] in %d passes",size, fname, cnt);
91 ::close(fd);
92}
93
Jiyoung Shinc15a6b02012-06-05 01:08:14 -070094int get_pixel_depth(uint32_t fmt)
95{
96 int depth = 0;
97
98 switch (fmt) {
99 case V4L2_PIX_FMT_JPEG:
100 depth = 8;
101 break;
102
103 case V4L2_PIX_FMT_NV12:
104 case V4L2_PIX_FMT_NV21:
105 case V4L2_PIX_FMT_YUV420:
106 case V4L2_PIX_FMT_YVU420M:
107 case V4L2_PIX_FMT_NV12M:
108 case V4L2_PIX_FMT_NV12MT:
109 depth = 12;
110 break;
111
112 case V4L2_PIX_FMT_RGB565:
113 case V4L2_PIX_FMT_YUYV:
114 case V4L2_PIX_FMT_YVYU:
115 case V4L2_PIX_FMT_UYVY:
116 case V4L2_PIX_FMT_VYUY:
117 case V4L2_PIX_FMT_NV16:
118 case V4L2_PIX_FMT_NV61:
119 case V4L2_PIX_FMT_YUV422P:
120 case V4L2_PIX_FMT_SBGGR10:
121 case V4L2_PIX_FMT_SBGGR12:
122 case V4L2_PIX_FMT_SBGGR16:
123 depth = 16;
124 break;
125
126 case V4L2_PIX_FMT_RGB32:
127 depth = 32;
128 break;
129 default:
130 ALOGE("Get depth failed(format : %d)", fmt);
131 break;
132 }
133
134 return depth;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900135}
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700136
137int cam_int_s_fmt(node_info_t *node)
138{
139 struct v4l2_format v4l2_fmt;
140 unsigned int framesize;
141 int ret;
142
143 memset(&v4l2_fmt, 0, sizeof(struct v4l2_format));
144
145 v4l2_fmt.type = node->type;
146 framesize = (node->width * node->height * get_pixel_depth(node->format)) / 8;
147
148 if (node->planes >= 1) {
149 v4l2_fmt.fmt.pix_mp.width = node->width;
150 v4l2_fmt.fmt.pix_mp.height = node->height;
151 v4l2_fmt.fmt.pix_mp.pixelformat = node->format;
152 v4l2_fmt.fmt.pix_mp.field = V4L2_FIELD_ANY;
153 } else {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900154 ALOGE("%s:S_FMT, Out of bound : Number of element plane",__FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700155 }
156
157 /* Set up for capture */
158 ret = exynos_v4l2_s_fmt(node->fd, &v4l2_fmt);
159
160 if (ret < 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900161 ALOGE("%s: exynos_v4l2_s_fmt fail (%d)",__FUNCTION__, ret);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700162
163 return ret;
164}
165
166int cam_int_reqbufs(node_info_t *node)
167{
168 struct v4l2_requestbuffers req;
169 int ret;
170
171 req.count = node->buffers;
172 req.type = node->type;
173 req.memory = node->memory;
174
175 ret = exynos_v4l2_reqbufs(node->fd, &req);
176
177 if (ret < 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900178 ALOGE("%s: VIDIOC_REQBUFS (fd:%d) failed (%d)",__FUNCTION__,node->fd, ret);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700179
180 return req.count;
181}
182
183int cam_int_qbuf(node_info_t *node, int index)
184{
185 struct v4l2_buffer v4l2_buf;
186 struct v4l2_plane planes[VIDEO_MAX_PLANES];
187 int i;
188 int ret = 0;
189
190 v4l2_buf.m.planes = planes;
191 v4l2_buf.type = node->type;
192 v4l2_buf.memory = node->memory;
193 v4l2_buf.index = index;
194 v4l2_buf.length = node->planes;
195
196 for(i = 0; i < node->planes; i++){
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900197 v4l2_buf.m.planes[i].m.fd = (int)(node->buffer[index].fd.extFd[i]);
198 v4l2_buf.m.planes[i].length = (unsigned long)(node->buffer[index].size.extS[i]);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700199 }
200
201 ret = exynos_v4l2_qbuf(node->fd, &v4l2_buf);
202
203 if (ret < 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900204 ALOGE("%s: cam_int_qbuf failed (index:%d)(ret:%d)",__FUNCTION__, index, ret);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700205
206 return ret;
207}
208
209int cam_int_streamon(node_info_t *node)
210{
211 enum v4l2_buf_type type = node->type;
212 int ret;
213
214 ret = exynos_v4l2_streamon(node->fd, type);
215
216 if (ret < 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900217 ALOGE("%s: VIDIOC_STREAMON failed (%d)",__FUNCTION__, ret);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700218
219 ALOGV("On streaming I/O... ... fd(%d)", node->fd);
220
221 return ret;
222}
223
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900224int cam_int_streamoff(node_info_t *node)
225{
226 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
227 int ret;
228
229 ALOGV("Off streaming I/O... fd(%d)", node->fd);
230 ret = exynos_v4l2_streamoff(node->fd, type);
231
232 if (ret < 0)
233 ALOGE("%s: VIDIOC_STREAMOFF failed (%d)",__FUNCTION__, ret);
234
235 return ret;
236}
237
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900238int isp_int_streamoff(node_info_t *node)
239{
240 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
241 int ret;
242
243 ALOGV("Off streaming I/O... fd(%d)", node->fd);
244 ret = exynos_v4l2_streamoff(node->fd, type);
245
246 if (ret < 0)
247 ALOGE("%s: VIDIOC_STREAMOFF failed (%d)",__FUNCTION__, ret);
248
249 return ret;
250}
251
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700252int cam_int_dqbuf(node_info_t *node)
253{
254 struct v4l2_buffer v4l2_buf;
255 struct v4l2_plane planes[VIDEO_MAX_PLANES];
256 int ret;
257
258 v4l2_buf.type = node->type;
259 v4l2_buf.memory = node->memory;
260 v4l2_buf.m.planes = planes;
261 v4l2_buf.length = node->planes;
262
263 ret = exynos_v4l2_dqbuf(node->fd, &v4l2_buf);
264 if (ret < 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900265 ALOGE("%s: VIDIOC_DQBUF failed (%d)",__FUNCTION__, ret);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700266
267 return v4l2_buf.index;
268}
269
270int cam_int_s_input(node_info_t *node, int index)
271{
272 int ret;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900273
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700274 ret = exynos_v4l2_s_input(node->fd, index);
275 if (ret < 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900276 ALOGE("%s: VIDIOC_S_INPUT failed (%d)",__FUNCTION__, ret);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700277
278 return ret;
279}
280
281
282gralloc_module_t const* ExynosCameraHWInterface2::m_grallocHal;
283
284RequestManager::RequestManager(SignalDrivenThread* main_thread):
285 m_numOfEntries(0),
286 m_entryInsertionIndex(0),
287 m_entryProcessingIndex(0),
288 m_entryFrameOutputIndex(0)
289{
290 m_metadataConverter = new MetadataConverter;
291 m_mainThread = main_thread;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900292 for (int i=0 ; i<NUM_MAX_REQUEST_MGR_ENTRY; i++) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900293 memset(&(entries[i]), 0x00, sizeof(request_manager_entry_t));
294 entries[i].internal_shot.ctl.request.frameCount = -1;
295 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -0700296 m_sensorPipelineSkipCnt = 8;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700297 return;
298}
299
300RequestManager::~RequestManager()
301{
302 return;
303}
304
305int RequestManager::GetNumEntries()
306{
307 return m_numOfEntries;
308}
309
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900310void RequestManager::SetDefaultParameters(int cropX)
311{
312 m_cropX = cropX;
313}
314
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700315bool RequestManager::IsRequestQueueFull()
316{
317 Mutex::Autolock lock(m_requestMutex);
318 if (m_numOfEntries>=NUM_MAX_REQUEST_MGR_ENTRY)
319 return true;
320 else
321 return false;
322}
323
324void RequestManager::RegisterRequest(camera_metadata_t * new_request)
325{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900326 ALOGV("DEBUG(%s):", __FUNCTION__);
327
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700328 Mutex::Autolock lock(m_requestMutex);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900329
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700330 request_manager_entry * newEntry = NULL;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900331 int newInsertionIndex = GetNextIndex(m_entryInsertionIndex);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900332 ALOGV("DEBUG(%s): got lock, new insertIndex(%d), cnt before reg(%d)", __FUNCTION__,newInsertionIndex,m_numOfEntries );
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700333
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900334
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700335 newEntry = &(entries[newInsertionIndex]);
336
337 if (newEntry->status!=EMPTY) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900338 ALOGV("DEBUG(%s): Circular buffer abnormal ", __FUNCTION__);
339 return;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700340 }
341 newEntry->status = REGISTERED;
342 newEntry->original_request = new_request;
343 // TODO : allocate internal_request dynamically
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900344 m_metadataConverter->ToInternalShot(new_request, &(newEntry->internal_shot));
345 newEntry->output_stream_count = newEntry->internal_shot.ctl.request.numOutputStream;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700346
347 m_numOfEntries++;
348 m_entryInsertionIndex = newInsertionIndex;
349
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900350
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900351 // Dump();
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700352 ALOGV("## RegisterReq DONE num(%d), insert(%d), processing(%d), frame(%d), (frameCnt(%d))",
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900353 m_numOfEntries,m_entryInsertionIndex,m_entryProcessingIndex, m_entryFrameOutputIndex, newEntry->internal_shot.ctl.request.frameCount);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700354}
355
356void RequestManager::DeregisterRequest(camera_metadata_t ** deregistered_request)
357{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900358 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700359 Mutex::Autolock lock(m_requestMutex);
360
361 request_manager_entry * currentEntry = &(entries[m_entryFrameOutputIndex]);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900362
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700363 if (currentEntry->status!=PROCESSING) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900364 ALOGD("DBG(%s): Circular buffer abnormal. processing(%d), frame(%d), status(%d) ", __FUNCTION__
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700365 , m_entryProcessingIndex, m_entryFrameOutputIndex,(int)(currentEntry->status));
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900366 return;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700367 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900368 if (deregistered_request) *deregistered_request = currentEntry->original_request;
369
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700370 currentEntry->status = EMPTY;
371 currentEntry->original_request = NULL;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900372 memset(&(currentEntry->internal_shot), 0, sizeof(camera2_ctl_metadata_NEW_t));
373 currentEntry->internal_shot.ctl.request.frameCount = -1;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700374 currentEntry->output_stream_count = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900375 currentEntry->dynamic_meta_vaild = false;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700376 m_numOfEntries--;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900377 // Dump();
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700378 ALOGV("## DeRegistReq DONE num(%d), insert(%d), processing(%d), frame(%d)",
379 m_numOfEntries,m_entryInsertionIndex,m_entryProcessingIndex, m_entryFrameOutputIndex);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900380
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700381 return;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700382}
383
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900384bool RequestManager::PrepareFrame(size_t* num_entries, size_t* frame_size,
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700385 camera_metadata_t ** prepared_frame)
386{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900387 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700388 Mutex::Autolock lock(m_requestMutex);
389 status_t res = NO_ERROR;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900390 int tempFrameOutputIndex = GetNextIndex(m_entryFrameOutputIndex);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900391 request_manager_entry * currentEntry = &(entries[tempFrameOutputIndex]);
392 ALOGV("DEBUG(%s): processing(%d), frameOut(%d), insert(%d) recentlycompleted(%d)", __FUNCTION__,
393 m_entryProcessingIndex, m_entryFrameOutputIndex, m_entryInsertionIndex, m_completedIndex);
394
395 if (m_completedIndex != tempFrameOutputIndex) {
396 ALOGV("DEBUG(%s): frame left behind : completed(%d), preparing(%d)", __FUNCTION__, m_completedIndex,tempFrameOutputIndex);
397
398 request_manager_entry * currentEntry2 = &(entries[tempFrameOutputIndex]);
399 currentEntry2->status = EMPTY;
400 currentEntry2->original_request = NULL;
401 memset(&(currentEntry2->internal_shot), 0, sizeof(camera2_ctl_metadata_NEW_t));
402 currentEntry2->internal_shot.ctl.request.frameCount = -1;
403 currentEntry2->output_stream_count = 0;
404 currentEntry2->dynamic_meta_vaild = false;
405 m_numOfEntries--;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900406 // Dump();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900407 tempFrameOutputIndex = m_completedIndex;
408 currentEntry = &(entries[tempFrameOutputIndex]);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700409 }
410
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900411 if (currentEntry->output_stream_count!=0) {
412 ALOGD("DBG(%s): Circular buffer has remaining output : stream_count(%d)", __FUNCTION__, currentEntry->output_stream_count);
413 return false;
414 }
415
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900416 if (currentEntry->status!=PROCESSING) {
417 ALOGD("DBG(%s): Circular buffer abnormal status(%d)", __FUNCTION__, (int)(currentEntry->status));
418
419 return false;
420 }
421 m_entryFrameOutputIndex = tempFrameOutputIndex;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700422 m_tempFrameMetadata = place_camera_metadata(m_tempFrameMetadataBuf, 2000, 10, 500); //estimated
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900423 res = m_metadataConverter->ToDynamicMetadata(&(currentEntry->internal_shot),
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700424 m_tempFrameMetadata);
425 if (res!=NO_ERROR) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900426 ALOGE("ERROR(%s): ToDynamicMetadata (%d) ", __FUNCTION__, res);
427 return false;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700428 }
429 *num_entries = get_camera_metadata_entry_count(m_tempFrameMetadata);
430 *frame_size = get_camera_metadata_size(m_tempFrameMetadata);
431 *prepared_frame = m_tempFrameMetadata;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900432 ALOGV("## PrepareFrame DONE: frameOut(%d) frameCnt-req(%d)", m_entryFrameOutputIndex,
433 currentEntry->internal_shot.ctl.request.frameCount);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900434 // Dump();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900435 return true;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700436}
437
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900438int RequestManager::MarkProcessingRequest(ExynosBuffer* buf)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700439{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900440 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700441 Mutex::Autolock lock(m_requestMutex);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900442 struct camera2_shot_ext * shot_ext;
443 int targetStreamIndex = 0;
444
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900445 if (m_numOfEntries == 0) {
446 ALOGV("DEBUG(%s): Request Manager Empty ", __FUNCTION__);
447 return -1;
448 }
449
450 if ((m_entryProcessingIndex == m_entryInsertionIndex)
451 && (entries[m_entryProcessingIndex].status == PROCESSING)) {
452 ALOGV("## MarkProcReq skipping(request underrun) - num(%d), insert(%d), processing(%d), frame(%d)",
453 m_numOfEntries,m_entryInsertionIndex,m_entryProcessingIndex, m_entryFrameOutputIndex);
454 return -1;
455 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700456
457 request_manager_entry * newEntry = NULL;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900458 int newProcessingIndex = GetNextIndex(m_entryProcessingIndex);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700459
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700460 newEntry = &(entries[newProcessingIndex]);
461
462 if (newEntry->status!=REGISTERED) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900463 ALOGV("DEBUG(%s): Circular buffer abnormal ", __FUNCTION__);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900464 // Dump();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900465 return -1;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700466 }
467 newEntry->status = PROCESSING;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900468 // TODO : replace the codes below with a single memcpy of pre-converted 'shot'
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700469
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900470 shot_ext = (struct camera2_shot_ext *)(buf->virt.extP[1]);
471 memset(shot_ext, 0x00, sizeof(struct camera2_shot_ext));
472
473 shot_ext->request_sensor = 1;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900474 shot_ext->dis_bypass = 1;
475 shot_ext->dnr_bypass = 1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900476 for (int i = 0; i < newEntry->output_stream_count; i++) {
477 // TODO : match with actual stream index;
478 targetStreamIndex = newEntry->internal_shot.ctl.request.outputStreams[i];
479
480 if (targetStreamIndex==0) {
481 ALOGV("DEBUG(%s): outputstreams(%d) is for scalerP", __FUNCTION__, i);
482 shot_ext->request_scp = 1;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900483 shot_ext->shot.ctl.request.outputStreams[0] = 1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900484 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900485 else if (targetStreamIndex == 1) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900486 ALOGV("DEBUG(%s): outputstreams(%d) is for scalerC", __FUNCTION__, i);
487 shot_ext->request_scc = 1;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900488 shot_ext->shot.ctl.request.outputStreams[1] = 1;
489 }
490 else if (targetStreamIndex == 2) {
491 ALOGV("DEBUG(%s): outputstreams(%d) is for scalerP (record)", __FUNCTION__, i);
492 shot_ext->request_scp = 1;
493 shot_ext->shot.ctl.request.outputStreams[2] = 1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900494 }
495 else {
496 ALOGV("DEBUG(%s): outputstreams(%d) has abnormal value(%d)", __FUNCTION__, i, targetStreamIndex);
497 }
498 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900499 shot_ext->shot.ctl.request.metadataMode = METADATA_MODE_FULL;
500 shot_ext->shot.magicNumber = 0x23456789;
501 shot_ext->shot.ctl.sensor.exposureTime = 0;
502 shot_ext->shot.ctl.sensor.frameDuration = 33*1000*1000;
503 shot_ext->shot.ctl.sensor.sensitivity = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900504
505 shot_ext->shot.ctl.scaler.cropRegion[0] = 0;
506 shot_ext->shot.ctl.scaler.cropRegion[1] = 0;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900507 shot_ext->shot.ctl.scaler.cropRegion[2] = m_cropX;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900508
509 m_entryProcessingIndex = newProcessingIndex;
510
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900511 // Dump();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900512 ALOGV("## MarkProcReq DONE totalentry(%d), insert(%d), processing(%d), frame(%d) frameCnt(%d)",
513 m_numOfEntries,m_entryInsertionIndex,m_entryProcessingIndex, m_entryFrameOutputIndex, newEntry->internal_shot.ctl.request.frameCount);
514
515 return m_entryProcessingIndex;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700516}
517
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900518void RequestManager::NotifyStreamOutput(int frameCnt, int stream_id)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700519{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900520 int index;
521
522 ALOGV("DEBUG(%s): frameCnt(%d), stream_id(%d)", __FUNCTION__, frameCnt, stream_id);
523
524 index = FindEntryIndexByFrameCnt(frameCnt);
525 if (index == -1) {
526 ALOGE("ERR(%s): Cannot find entry for frameCnt(%d)", __FUNCTION__, frameCnt);
527 return;
528 }
529 ALOGV("DEBUG(%s): frameCnt(%d), stream_id(%d) last cnt (%d)", __FUNCTION__, frameCnt, stream_id, entries[index].output_stream_count);
530
Sungjoong Kangb5237e62012-07-27 07:39:05 -0700531 if (entries[index].output_stream_count == 0) {
532 ALOGV("(%s): applying to next frame", __FUNCTION__);
533 entries[GetNextIndex(index)].output_stream_count--;
534 }
535 else {
536 entries[index].output_stream_count--; //TODO : match stream id also
537 CheckCompleted(index);
538 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700539 return;
540}
541
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900542void RequestManager::CheckCompleted(int index)
543{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900544 ALOGV("DEBUG(%s): reqIndex(%d) current Count(%d)", __FUNCTION__, index, entries[index].output_stream_count);
Sungjoong Kangb5237e62012-07-27 07:39:05 -0700545 if (entries[index].output_stream_count == 0 && entries[index].dynamic_meta_vaild) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900546 ALOGV("DEBUG(%s): index[%d] completed and sending SIGNAL_MAIN_STREAM_OUTPUT_DONE", __FUNCTION__, index);
Sungjoong Kangb5237e62012-07-27 07:39:05 -0700547 // Dump();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900548 m_completedIndex = index;
549 m_mainThread->SetSignal(SIGNAL_MAIN_STREAM_OUTPUT_DONE);
550 }
551 return;
552}
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900553
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900554void RequestManager::ApplyDynamicMetadata(struct camera2_shot_ext *shot_ext, int frameCnt)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900555{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900556 int index;
557
558 ALOGV("DEBUG(%s): frameCnt(%d)", __FUNCTION__, frameCnt);
559
560 index = FindEntryIndexByFrameCnt(frameCnt);
561 if (index == -1) {
562 ALOGE("ERR(%s): Cannot find entry for frameCnt(%d)", __FUNCTION__, frameCnt);
563 return;
564 }
565
566 request_manager_entry * newEntry = &(entries[index]);
567
Sungjoong Kangb5237e62012-07-27 07:39:05 -0700568 if (newEntry->dynamic_meta_vaild) {
569 ALOGV("(%s): applying to next frame", __FUNCTION__);
570 newEntry = &(entries[GetNextIndex(index)]);
571 newEntry->dynamic_meta_vaild = true;
572 }
573 else {
574 newEntry->dynamic_meta_vaild = true;
575 // TODO : move some code of PrepareFrame here
576 CheckCompleted(index);
577 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900578}
579
580void RequestManager::DumpInfoWithIndex(int index)
581{
582 camera2_ctl_metadata_NEW_t * currMetadata = &(entries[index].internal_shot);
583
584 ALOGV("#### frameCount(%d) exposureTime(%lld) ISO(%d)",
585 currMetadata->ctl.request.frameCount,
586 currMetadata->ctl.sensor.exposureTime,
587 currMetadata->ctl.sensor.sensitivity);
588 if (currMetadata->ctl.request.numOutputStream==0)
589 ALOGV("#### No output stream selected");
590 else if (currMetadata->ctl.request.numOutputStream==1)
591 ALOGV("#### OutputStreamId : %d", currMetadata->ctl.request.outputStreams[0]);
592 else if (currMetadata->ctl.request.numOutputStream==2)
593 ALOGV("#### OutputStreamId : %d, %d", currMetadata->ctl.request.outputStreams[0],
594 currMetadata->ctl.request.outputStreams[1]);
595 else
596 ALOGV("#### OutputStream num (%d) abnormal ", currMetadata->ctl.request.numOutputStream);
597}
598
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900599void RequestManager::UpdateOutputStreamInfo(struct camera2_shot_ext *shot_ext, int frameCnt)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900600{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900601 int index, targetStreamIndex;
602
603 ALOGV("DEBUG(%s): updating info with frameCnt(%d)", __FUNCTION__, frameCnt);
604 if (frameCnt < 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900605 return;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900606
607 index = FindEntryIndexByFrameCnt(frameCnt);
608 if (index == -1) {
609 ALOGE("ERR(%s): Cannot find entry for frameCnt(%d)", __FUNCTION__, frameCnt);
610 return;
611 }
612
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900613 request_manager_entry * newEntry = &(entries[index]);
614 shot_ext->request_sensor = 1;
615 shot_ext->request_scc = 0;
616 shot_ext->request_scp = 0;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900617 shot_ext->shot.ctl.request.outputStreams[0] = 0;
618 shot_ext->shot.ctl.request.outputStreams[1] = 0;
619 shot_ext->shot.ctl.request.outputStreams[2] = 0;
620
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900621 for (int i = 0; i < newEntry->output_stream_count; i++) {
622 // TODO : match with actual stream index;
623 targetStreamIndex = newEntry->internal_shot.ctl.request.outputStreams[i];
624
625 if (targetStreamIndex==0) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900626 ALOGV("DEBUG(%s): outputstreams item[%d] is for scalerP", __FUNCTION__, i);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900627 shot_ext->request_scp = 1;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900628 shot_ext->shot.ctl.request.outputStreams[0] = 1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900629 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900630 else if (targetStreamIndex == 1) {
631 ALOGV("DEBUG(%s): outputstreams item[%d] is for scalerC", __FUNCTION__, i);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900632 shot_ext->request_scc = 1;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900633 shot_ext->shot.ctl.request.outputStreams[1] = 1;
634 }
635 else if (targetStreamIndex == 2) {
636 ALOGV("DEBUG(%s): outputstreams item[%d] is for scalerP (record)", __FUNCTION__, i);
637 shot_ext->request_scp = 1;
638 shot_ext->shot.ctl.request.outputStreams[2] = 1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900639 }
640 else {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900641 ALOGV("DEBUG(%s): outputstreams item[%d] has abnormal value(%d)", __FUNCTION__, i, targetStreamIndex);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900642 }
643 }
644}
645
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900646int RequestManager::FindEntryIndexByFrameCnt(int frameCnt)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900647{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900648 for (int i = 0 ; i < NUM_MAX_REQUEST_MGR_ENTRY ; i++) {
649 if (entries[i].internal_shot.ctl.request.frameCount == frameCnt)
650 return i;
651 }
652 return -1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900653}
654
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900655void RequestManager::RegisterTimestamp(int frameCnt, nsecs_t * frameTime)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900656{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900657 int index = FindEntryIndexByFrameCnt(frameCnt);
658 if (index == -1) {
659 ALOGE("ERR(%s): Cannot find entry for frameCnt(%d)", __FUNCTION__, frameCnt);
660 return;
661 }
662
663 request_manager_entry * currentEntry = &(entries[index]);
664 currentEntry->internal_shot.dm.sensor.timeStamp = *((uint64_t*)frameTime);
665 ALOGV("DEBUG(%s): applied timestamp for reqIndex(%d) frameCnt(%d) (%lld)", __FUNCTION__,
666 index, frameCnt, currentEntry->internal_shot.dm.sensor.timeStamp);
667}
668
669uint64_t RequestManager::GetTimestamp(int frameCnt)
670{
671 int index = FindEntryIndexByFrameCnt(frameCnt);
672 if (index == -1) {
673 ALOGE("ERR(%s): Cannot find entry for frameCnt(%d)", __FUNCTION__, frameCnt);
674 return 0;
675 }
676
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900677 request_manager_entry * currentEntry = &(entries[index]);
678 uint64_t frameTime = currentEntry->internal_shot.dm.sensor.timeStamp;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900679 ALOGV("DEBUG(%s): Returning timestamp for reqIndex(%d) (%lld)", __FUNCTION__, index, frameTime);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900680 return frameTime;
681}
682
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900683int RequestManager::FindFrameCnt(struct camera2_shot_ext * shot_ext)
684{
685 int tempIndex;
Sungjoong Kangb5237e62012-07-27 07:39:05 -0700686 if (m_sensorPipelineSkipCnt > 0) {
687 m_sensorPipelineSkipCnt--;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900688 return -1;
689 }
690/*
691 * tempIndex = GetNextIndex(tempIndex);
692 * return entries[tempIndex].internal_shot.ctl.request.frameCount;
693 * */
694 tempIndex = GetNextIndex(m_entryFrameOutputIndex);
695 return entries[tempIndex].internal_shot.ctl.request.frameCount;
696}
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900697
Sungjoong Kangb5237e62012-07-27 07:39:05 -0700698void RequestManager::SetInitialSkip(int count)
699{
700 ALOGV("(%s): Pipeline Restarting. setting cnt(%d) - current(%d)", __FUNCTION__, count, m_sensorPipelineSkipCnt);
701 if (count > m_sensorPipelineSkipCnt)
702 m_sensorPipelineSkipCnt = count;
703}
704
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900705void RequestManager::Dump(void)
706{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900707 int i = 0;
708 request_manager_entry * currentEntry;
709 ALOGV("## Dump totalentry(%d), insert(%d), processing(%d), frame(%d)",
710 m_numOfEntries,m_entryInsertionIndex,m_entryProcessingIndex, m_entryFrameOutputIndex);
711
712 for (i = 0 ; i < NUM_MAX_REQUEST_MGR_ENTRY ; i++) {
713 currentEntry = &(entries[i]);
714 ALOGV("[%2d] status[%d] frameCnt[%3d] numOutput[%d]", i,
715 currentEntry->status, currentEntry->internal_shot.ctl.request.frameCount,
716 currentEntry->output_stream_count);
717 }
718}
719
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900720int RequestManager::GetNextIndex(int index)
721{
722 index++;
723 if (index >= NUM_MAX_REQUEST_MGR_ENTRY)
724 index = 0;
725
726 return index;
727}
728
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700729ExynosCameraHWInterface2::ExynosCameraHWInterface2(int cameraId, camera2_device_t *dev):
730 m_requestQueueOps(NULL),
731 m_frameQueueOps(NULL),
732 m_callbackCookie(NULL),
733 m_numOfRemainingReqInSvc(0),
734 m_isRequestQueuePending(false),
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900735 m_isRequestQueueNull(true),
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700736 m_isSensorThreadOn(false),
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900737 m_isSensorStarted(false),
738 m_ionCameraClient(0),
739 m_initFlag1(false),
740 m_initFlag2(false),
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900741 m_scp_flushing(false),
742 m_closing(false),
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900743 m_recordingEnabled(false),
744 m_needsRecordBufferInit(false),
745 lastFrameCnt(-1),
746 m_scp_closing(false),
747 m_scp_closed(false),
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900748 m_halDevice(dev),
Sungjoong Kangb5237e62012-07-27 07:39:05 -0700749 m_sensor_drop(false),
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900750 m_cameraId(0)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700751{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900752 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700753 int ret = 0;
754
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900755 m_exynosPictureCSC = NULL;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900756 m_exynosVideoCSC = NULL;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900757
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700758 if (!m_grallocHal) {
759 ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&m_grallocHal);
760 if (ret)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900761 ALOGE("ERR(%s):Fail on loading gralloc HAL", __FUNCTION__);
762 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700763
764 m_ionCameraClient = createIonClient(m_ionCameraClient);
765 if(m_ionCameraClient == 0)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900766 ALOGE("ERR(%s):Fail on ion_client_create", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700767
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900768 m_cameraId = cameraId;
769
770 m_BayerManager = new BayerBufManager();
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700771 m_mainThread = new MainThread(this);
772 m_sensorThread = new SensorThread(this);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900773 m_ispThread = new IspThread(this);
774 m_mainThread->Start("MainThread", PRIORITY_DEFAULT, 0);
775 ALOGV("DEBUG(%s): created sensorthread ################", __FUNCTION__);
776 usleep(1600000);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700777
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900778 m_requestManager = new RequestManager((SignalDrivenThread*)(m_mainThread.get()));
779 CSC_METHOD cscMethod = CSC_METHOD_HW;
780 m_exynosPictureCSC = csc_init(cscMethod);
781 if (m_exynosPictureCSC == NULL)
782 ALOGE("ERR(%s): csc_init() fail", __FUNCTION__);
783 csc_set_hw_property(m_exynosPictureCSC, CSC_HW_PROPERTY_FIXED_NODE, PICTURE_GSC_NODE_NUM);
784
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900785 m_exynosVideoCSC = csc_init(cscMethod);
786 if (m_exynosVideoCSC == NULL)
787 ALOGE("ERR(%s): csc_init() fail", __FUNCTION__);
788 csc_set_hw_property(m_exynosVideoCSC, CSC_HW_PROPERTY_FIXED_NODE, PREVIEW_GSC_NODE_NUM);
789
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900790 ALOGV("DEBUG(%s): END", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700791}
792
793ExynosCameraHWInterface2::~ExynosCameraHWInterface2()
794{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900795 ALOGD("%s: ENTER", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700796 this->release();
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900797 ALOGD("%s: EXIT", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700798}
799
800void ExynosCameraHWInterface2::release()
801{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900802 int i, res;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900803 ALOGD("%s: ENTER", __func__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900804 m_closing = true;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900805
806 while (!m_scp_closed)
807 usleep(1000);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900808 if (m_ispThread != NULL) {
809 m_ispThread->release();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900810 }
811
812 if (m_sensorThread != NULL) {
813 m_sensorThread->release();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900814 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700815
816 if (m_mainThread != NULL) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900817 m_mainThread->release();
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700818 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700819
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900820 if (m_streamThreads[0] != NULL) {
821 m_streamThreads[0]->release();
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900822 m_streamThreads[0]->SetSignal(SIGNAL_THREAD_TERMINATE);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700823 }
824
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900825 if (m_streamThreads[1] != NULL) {
826 m_streamThreads[1]->release();
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900827 m_streamThreads[1]->SetSignal(SIGNAL_THREAD_TERMINATE);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900828 }
829
830
831 if (m_exynosPictureCSC)
832 csc_deinit(m_exynosPictureCSC);
833 m_exynosPictureCSC = NULL;
834
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900835 if (m_exynosVideoCSC)
836 csc_deinit(m_exynosVideoCSC);
837 m_exynosVideoCSC = NULL;
838
839 if (m_ispThread != NULL) {
840 while (!m_ispThread->IsTerminated())
841 usleep(1000);
842 m_ispThread = NULL;
843 }
844
845 if (m_sensorThread != NULL) {
846 while (!m_sensorThread->IsTerminated())
847 usleep(1000);
848 m_sensorThread = NULL;
849 }
850
851 if (m_mainThread != NULL) {
852 while (!m_mainThread->IsTerminated())
853 usleep(1000);
854 m_mainThread = NULL;
855 }
856
857 if (m_streamThreads[0] != NULL) {
858 while (!m_streamThreads[0]->IsTerminated())
859 usleep(1000);
860 m_streamThreads[0] = NULL;
861 }
862
863 if (m_streamThreads[1] != NULL) {
864 while (!m_streamThreads[1]->IsTerminated())
865 usleep(1000);
866 m_streamThreads[1] = NULL;
867 }
868
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700869 for(i = 0; i < m_camera_info.sensor.buffers; i++)
870 freeCameraMemory(&m_camera_info.sensor.buffer[i], m_camera_info.sensor.planes);
871
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700872 for(i = 0; i < m_camera_info.capture.buffers; i++)
873 freeCameraMemory(&m_camera_info.capture.buffer[i], m_camera_info.capture.planes);
874
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900875 ALOGV("DEBUG(%s): calling exynos_v4l2_close - sensor", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900876 res = exynos_v4l2_close(m_camera_info.sensor.fd);
877 if (res != NO_ERROR ) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900878 ALOGE("ERR(%s): exynos_v4l2_close failed(%d)",__FUNCTION__ , res);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900879 }
880
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900881 ALOGV("DEBUG(%s): calling exynos_v4l2_close - isp", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900882 res = exynos_v4l2_close(m_camera_info.isp.fd);
883 if (res != NO_ERROR ) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900884 ALOGE("ERR(%s): exynos_v4l2_close failed(%d)",__FUNCTION__ , res);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900885 }
886
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900887 ALOGV("DEBUG(%s): calling exynos_v4l2_close - capture", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900888 res = exynos_v4l2_close(m_camera_info.capture.fd);
889 if (res != NO_ERROR ) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900890 ALOGE("ERR(%s): exynos_v4l2_close failed(%d)",__FUNCTION__ , res);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900891 }
892
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900893 ALOGV("DEBUG(%s): calling exynos_v4l2_close - scp", __FUNCTION__);
894 res = exynos_v4l2_close(m_fd_scp);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900895 if (res != NO_ERROR ) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900896 ALOGE("ERR(%s): exynos_v4l2_close failed(%d)",__FUNCTION__ , res);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900897 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900898 ALOGV("DEBUG(%s): calling deleteIonClient", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700899 deleteIonClient(m_ionCameraClient);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900900
901 ALOGD("%s: EXIT", __func__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900902}
903
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700904int ExynosCameraHWInterface2::getCameraId() const
905{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900906 return m_cameraId;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700907}
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700908
909int ExynosCameraHWInterface2::setRequestQueueSrcOps(const camera2_request_queue_src_ops_t *request_src_ops)
910{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900911 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700912 if ((NULL != request_src_ops) && (NULL != request_src_ops->dequeue_request)
913 && (NULL != request_src_ops->free_request) && (NULL != request_src_ops->request_count)) {
914 m_requestQueueOps = (camera2_request_queue_src_ops_t*)request_src_ops;
915 return 0;
916 }
917 else {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900918 ALOGE("DEBUG(%s):setRequestQueueSrcOps : NULL arguments", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700919 return 1;
920 }
921}
922
923int ExynosCameraHWInterface2::notifyRequestQueueNotEmpty()
924{
Sungjoong Kangb5237e62012-07-27 07:39:05 -0700925 ALOGV("DEBUG(%s):setting [SIGNAL_MAIN_REQ_Q_NOT_EMPTY] current(%d)", __FUNCTION__, m_requestManager->GetNumEntries());
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700926 if ((NULL==m_frameQueueOps)|| (NULL==m_requestQueueOps)) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900927 ALOGE("DEBUG(%s):queue ops NULL. ignoring request", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700928 return 0;
929 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900930 m_isRequestQueueNull = false;
Sungjoong Kangb5237e62012-07-27 07:39:05 -0700931 if (m_requestManager->GetNumEntries() == 0)
932 m_requestManager->SetInitialSkip(5);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700933 m_mainThread->SetSignal(SIGNAL_MAIN_REQ_Q_NOT_EMPTY);
934 return 0;
935}
936
937int ExynosCameraHWInterface2::setFrameQueueDstOps(const camera2_frame_queue_dst_ops_t *frame_dst_ops)
938{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900939 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700940 if ((NULL != frame_dst_ops) && (NULL != frame_dst_ops->dequeue_frame)
941 && (NULL != frame_dst_ops->cancel_frame) && (NULL !=frame_dst_ops->enqueue_frame)) {
942 m_frameQueueOps = (camera2_frame_queue_dst_ops_t *)frame_dst_ops;
943 return 0;
944 }
945 else {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900946 ALOGE("DEBUG(%s):setFrameQueueDstOps : NULL arguments", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700947 return 1;
948 }
949}
950
951int ExynosCameraHWInterface2::getInProgressCount()
952{
953 int inProgressCount = m_requestManager->GetNumEntries();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900954 ALOGV("DEBUG(%s): # of dequeued req (%d)", __FUNCTION__, inProgressCount);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700955 return inProgressCount;
956}
957
958int ExynosCameraHWInterface2::flushCapturesInProgress()
959{
960 return 0;
961}
962
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700963int ExynosCameraHWInterface2::constructDefaultRequest(int request_template, camera_metadata_t **request)
964{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900965 ALOGV("DEBUG(%s): making template (%d) ", __FUNCTION__, request_template);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700966
967 if (request == NULL) return BAD_VALUE;
968 if (request_template < 0 || request_template >= CAMERA2_TEMPLATE_COUNT) {
969 return BAD_VALUE;
970 }
971 status_t res;
972 // Pass 1, calculate size and allocate
973 res = constructDefaultRequestInternal(request_template,
974 request,
975 true);
976 if (res != OK) {
977 return res;
978 }
979 // Pass 2, build request
980 res = constructDefaultRequestInternal(request_template,
981 request,
982 false);
983 if (res != OK) {
984 ALOGE("Unable to populate new request for template %d",
985 request_template);
986 }
987
988 return res;
989}
990
991int ExynosCameraHWInterface2::allocateStream(uint32_t width, uint32_t height, int format, const camera2_stream_ops_t *stream_ops,
992 uint32_t *stream_id, uint32_t *format_actual, uint32_t *usage, uint32_t *max_buffers)
993{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900994 ALOGD("DEBUG(%s): allocate stream width(%d) height(%d) format(%x)", __FUNCTION__, width, height, format);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700995 char node_name[30];
Sungjoong Kang9dd63e12012-07-24 00:25:51 +0900996 int fd = 0, allocCase = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +0900997 StreamThread *AllocatedStream;
998 stream_parameters_t newParameters;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -0700999
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001000 if ((format == CAMERA2_HAL_PIXEL_FORMAT_OPAQUE &&
1001 isSupportedPreviewSize(m_cameraId, width, height))) {
1002 if (!(m_streamThreads[0].get())) {
1003 ALOGV("DEBUG(%s): stream 0 not exist", __FUNCTION__);
1004 allocCase = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001005 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001006 else {
Alex Ray6bbb5932012-07-27 17:19:48 -07001007 if ((m_streamThreads[0].get())->m_activated == true) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001008 ALOGV("DEBUG(%s): stream 0 exists and activated.", __FUNCTION__);
1009 allocCase = 1;
1010 }
1011 else {
1012 ALOGV("DEBUG(%s): stream 0 exists and deactivated.", __FUNCTION__);
1013 allocCase = 2;
1014 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001015 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001016 if (allocCase == 0 || allocCase == 2) {
1017 *stream_id = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001018
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001019 if (allocCase == 0) {
1020 m_streamThreads[0] = new StreamThread(this, *stream_id);
1021
1022
1023 memset(&node_name, 0x00, sizeof(char[30]));
1024 sprintf(node_name, "%s%d", NODE_PREFIX, 44);
1025 fd = exynos_v4l2_open(node_name, O_RDWR, 0);
1026 if (fd < 0) {
1027 ALOGE("DEBUG(%s): failed to open preview video node (%s) fd (%d)", __FUNCTION__,node_name, fd);
1028 }
1029 else {
1030 ALOGV("DEBUG(%s): preview video node opened(%s) fd (%d)", __FUNCTION__,node_name, fd);
1031 }
1032 m_fd_scp = fd;
1033 }
1034 AllocatedStream = (StreamThread*)(m_streamThreads[0].get());
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001035 m_scp_flushing = false;
1036 m_scp_closing = false;
1037 m_scp_closed = false;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001038 usleep(100000); // TODO : guarantee the codes below will be run after readyToRunInternal()
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001039
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001040 *format_actual = HAL_PIXEL_FORMAT_YV12;
Alex Ray6bbb5932012-07-27 17:19:48 -07001041 *usage = GRALLOC_USAGE_SW_WRITE_OFTEN;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001042 *max_buffers = 8;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001043
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001044 newParameters.streamType = 0;
1045 newParameters.outputWidth = width;
1046 newParameters.outputHeight = height;
1047 newParameters.nodeWidth = width;
1048 newParameters.nodeHeight = height;
1049 newParameters.outputFormat = *format_actual;
1050 newParameters.nodeFormat = HAL_PIXEL_FORMAT_2_V4L2_PIX(*format_actual);
1051 newParameters.streamOps = stream_ops;
1052 newParameters.usage = *usage;
1053 newParameters.numHwBuffers = *max_buffers;
1054 newParameters.fd = m_fd_scp;
1055 newParameters.nodePlanes = 3;
1056 newParameters.svcPlanes = 3;
1057 newParameters.halBuftype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1058 newParameters.memory = V4L2_MEMORY_DMABUF;
1059 newParameters.ionClient = m_ionCameraClient;
1060 AllocatedStream->m_index = *stream_id;
1061 AllocatedStream->setParameter(&newParameters);
1062 AllocatedStream->m_activated = true;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001063
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001064 m_scp_flushing = false;
1065 m_scp_closing = false;
1066 m_scp_closed = false;
1067 m_requestManager->SetDefaultParameters(width);
1068 m_camera_info.dummy_shot.shot.ctl.scaler.cropRegion[2] = width;
1069 return 0;
1070 }
1071 else if (allocCase == 1) {
1072 record_parameters_t recordParameters;
1073 StreamThread *parentStream;
1074 parentStream = (StreamThread*)(m_streamThreads[0].get());
1075 if (!parentStream) {
1076 return 1;
1077 // TODO
1078 }
1079 *stream_id = 2;
1080 usleep(100000); // TODO : guarantee the codes below will be run after readyToRunInternal()
1081
1082 *format_actual = HAL_PIXEL_FORMAT_RGBA_8888;
Alex Ray6bbb5932012-07-27 17:19:48 -07001083 *usage = GRALLOC_USAGE_SW_WRITE_OFTEN;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001084 *max_buffers = 10;
1085
1086 recordParameters.outputWidth = width;
1087 recordParameters.outputHeight = height;
1088 recordParameters.outputFormat = *format_actual;
1089 recordParameters.svcPlanes = 1;
1090 recordParameters.streamOps = stream_ops;
1091 recordParameters.usage = *usage;
1092 recordParameters.numBufsInHal = 0;
1093
1094 parentStream->setRecordingParameter(&recordParameters);
1095 m_scp_flushing = false;
1096 m_scp_closing = false;
1097 m_scp_closed = false;
1098 m_recordingEnabled = true;
1099 return 0;
1100 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001101 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001102 else if (format == HAL_PIXEL_FORMAT_BLOB
1103 && isSupportedJpegSize(m_cameraId, width, height)) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001104
1105 *stream_id = 1;
1106
1107 m_streamThreads[1] = new StreamThread(this, *stream_id);
1108 AllocatedStream = (StreamThread*)(m_streamThreads[1].get());
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001109
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001110 fd = m_camera_info.capture.fd;
1111 usleep(100000); // TODO : guarantee the codes below will be run after readyToRunInternal()
1112
1113 *format_actual = HAL_PIXEL_FORMAT_BLOB;
1114
1115 *usage = GRALLOC_USAGE_SW_WRITE_OFTEN;
1116 *max_buffers = 8;
1117
1118 newParameters.streamType = 1;
1119 newParameters.outputWidth = width;
1120 newParameters.outputHeight = height;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001121
1122 newParameters.nodeWidth = getSccOutputSizeX(m_cameraId);
1123 newParameters.nodeHeight = getSccOutputSizeY(m_cameraId);
1124
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001125 newParameters.outputFormat = *format_actual;
1126 newParameters.nodeFormat = V4L2_PIX_FMT_YUYV;
1127 newParameters.streamOps = stream_ops;
1128 newParameters.usage = *usage;
1129 newParameters.numHwBuffers = *max_buffers;
1130 newParameters.fd = fd;
1131 newParameters.nodePlanes = 1;
1132 newParameters.svcPlanes = 1;
1133 newParameters.halBuftype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1134 newParameters.memory = V4L2_MEMORY_DMABUF;
1135 newParameters.ionClient = m_ionCameraClient;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001136 AllocatedStream->m_index = *stream_id;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001137 AllocatedStream->setParameter(&newParameters);
1138 return 0;
1139 }
1140 ALOGE("DEBUG(%s): Unsupported Pixel Format", __FUNCTION__);
1141 return 1; // TODO : check proper error code
1142}
1143
1144int ExynosCameraHWInterface2::registerStreamBuffers(uint32_t stream_id,
1145 int num_buffers, buffer_handle_t *registeringBuffers)
1146{
1147 int i,j;
1148 void *virtAddr[3];
1149 uint32_t plane_index = 0;
1150 stream_parameters_t *targetStreamParms;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001151 record_parameters_t *targetRecordParms;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001152 node_info_t *currentNode;
1153
1154 struct v4l2_buffer v4l2_buf;
1155 struct v4l2_plane planes[VIDEO_MAX_PLANES];
1156
1157 ALOGV("DEBUG(%s): streamID (%d), num_buff(%d), handle(%x) ", __FUNCTION__,
1158 stream_id, num_buffers, (uint32_t)registeringBuffers);
1159
1160 if (stream_id == 0) {
1161 targetStreamParms = &(m_streamThreads[0]->m_parameters);
1162 }
1163 else if (stream_id == 1) {
1164 targetStreamParms = &(m_streamThreads[1]->m_parameters);
1165 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001166 else if (stream_id == 2) {
1167 targetRecordParms = &(m_streamThreads[0]->m_recordParameters);
1168
1169 targetRecordParms->numSvcBuffers = num_buffers;
1170
1171 for (i = 0 ; i<targetRecordParms->numSvcBuffers ; i++) {
1172 ALOGV("DEBUG(%s): registering Stream Buffers[%d] (%x) ", __FUNCTION__,
1173 i, (uint32_t)(registeringBuffers[i]));
1174 if (m_grallocHal) {
1175 if (m_grallocHal->lock(m_grallocHal, registeringBuffers[i],
1176 targetRecordParms->usage, 0, 0,
1177 targetRecordParms->outputWidth, targetRecordParms->outputHeight, virtAddr) != 0) {
1178 ALOGE("ERR(%s): could not obtain gralloc buffer", __FUNCTION__);
1179 }
1180 else {
1181 ExynosBuffer currentBuf;
1182 const private_handle_t *priv_handle = reinterpret_cast<const private_handle_t *>(registeringBuffers[i]);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001183 //m_getAlignedYUVSize(HAL_PIXEL_FORMAT_2_V4L2_PIX(targetRecordParms->outputFormat),
1184 // targetRecordParms->outputWidth, targetRecordParms->outputHeight, &currentBuf);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001185 currentBuf.fd.extFd[0] = priv_handle->fd;
Alex Ray6bbb5932012-07-27 17:19:48 -07001186 currentBuf.fd.extFd[1] = priv_handle->fd1;
1187 currentBuf.fd.extFd[2] = priv_handle->fd2;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001188 ALOGV("DEBUG(%s): yddr(%x), uoffset(%d), voffset(%d)", __FUNCTION__,priv_handle->yaddr, priv_handle->uoffset, priv_handle->voffset);
1189 ALOGV("DEBUG(%s): ion_size(%d), stride(%d), ", __FUNCTION__,priv_handle->size, priv_handle->stride);
1190 for (plane_index=0 ; plane_index < targetRecordParms->svcPlanes ; plane_index++) {
1191 currentBuf.virt.extP[plane_index] = (char *)virtAddr[plane_index];
1192 ALOGV("DEBUG(%s): plane(%d): fd(%d) addr(%x)",
1193 __FUNCTION__, plane_index, currentBuf.fd.extFd[i],
1194 (unsigned int)currentBuf.virt.extP[plane_index]);
1195 }
1196 targetRecordParms->svcBufStatus[i] = ON_SERVICE;
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001197 targetRecordParms->svcBuffers[i] = currentBuf;
1198 targetRecordParms->svcBufHandle[i] = registeringBuffers[i];
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001199 }
1200 }
1201 }
1202 m_needsRecordBufferInit = true;
1203 return 0;
1204 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001205 else {
1206 ALOGE("ERR(%s) unregisterd stream id (%d)", __FUNCTION__, stream_id);
1207 return 1; // TODO : proper error code?
1208 }
1209
1210 if (targetStreamParms->streamType ==0) {
1211 if (num_buffers < targetStreamParms->numHwBuffers) {
1212 ALOGE("ERR(%s) registering insufficient num of buffers (%d) < (%d)",
1213 __FUNCTION__, num_buffers, targetStreamParms->numHwBuffers);
1214 return 1; // TODO : proper error code?
1215 }
1216 }
1217 ALOGV("DEBUG(%s): format(%x) width(%d), height(%d) svcPlanes(%d)",
1218 __FUNCTION__, targetStreamParms->outputFormat, targetStreamParms->outputWidth,
1219 targetStreamParms->outputHeight, targetStreamParms->svcPlanes);
1220
1221 targetStreamParms->numSvcBuffers = num_buffers;
1222 currentNode = &(targetStreamParms->node); // TO Remove
1223
1224 currentNode->fd = targetStreamParms->fd;
1225 currentNode->width = targetStreamParms->nodeWidth;
1226 currentNode->height = targetStreamParms->nodeHeight;
1227 currentNode->format = targetStreamParms->nodeFormat;
1228 currentNode->planes = targetStreamParms->nodePlanes;
1229 currentNode->buffers = targetStreamParms->numHwBuffers;
1230 currentNode->type = targetStreamParms->halBuftype;
1231 currentNode->memory = targetStreamParms->memory;
1232 currentNode->ionClient = targetStreamParms->ionClient;
1233
1234 if (targetStreamParms->streamType == 0) {
1235 cam_int_s_input(currentNode, m_camera_info.sensor_id);
1236 cam_int_s_fmt(currentNode);
1237 cam_int_reqbufs(currentNode);
1238 }
1239 else if (targetStreamParms->streamType == 1) {
1240 for(i = 0; i < currentNode->buffers; i++){
1241 memcpy(&(currentNode->buffer[i]), &(m_camera_info.capture.buffer[i]), sizeof(ExynosBuffer));
1242 }
1243 }
1244
1245 for (i = 0 ; i<targetStreamParms->numSvcBuffers ; i++) {
1246 ALOGV("DEBUG(%s): registering Stream Buffers[%d] (%x) ", __FUNCTION__,
1247 i, (uint32_t)(registeringBuffers[i]));
1248 if (m_grallocHal) {
1249 if (m_grallocHal->lock(m_grallocHal, registeringBuffers[i],
1250 targetStreamParms->usage, 0, 0,
1251 currentNode->width, currentNode->height, virtAddr) != 0) {
1252 ALOGE("ERR(%s): could not obtain gralloc buffer", __FUNCTION__);
1253 }
1254 else {
1255 v4l2_buf.m.planes = planes;
1256 v4l2_buf.type = currentNode->type;
1257 v4l2_buf.memory = currentNode->memory;
1258 v4l2_buf.index = i;
1259 v4l2_buf.length = currentNode->planes;
1260
1261 ExynosBuffer currentBuf;
1262 const private_handle_t *priv_handle = reinterpret_cast<const private_handle_t *>(registeringBuffers[i]);
1263
1264 m_getAlignedYUVSize(currentNode->format,
1265 currentNode->width, currentNode->height, &currentBuf);
Alex Ray24231222012-06-27 15:18:15 -07001266
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001267 v4l2_buf.m.planes[0].m.fd = priv_handle->fd;
Alex Ray6bbb5932012-07-27 17:19:48 -07001268 v4l2_buf.m.planes[2].m.fd = priv_handle->fd1;
1269 v4l2_buf.m.planes[1].m.fd = priv_handle->fd2;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001270 currentBuf.fd.extFd[0] = priv_handle->fd;
Alex Ray6bbb5932012-07-27 17:19:48 -07001271 currentBuf.fd.extFd[2] = priv_handle->fd1;
1272 currentBuf.fd.extFd[1] = priv_handle->fd2;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001273 ALOGV("DEBUG(%s): yddr(%x), uoffset(%d), voffset(%d)", __FUNCTION__,priv_handle->yaddr, priv_handle->uoffset, priv_handle->voffset);
1274 ALOGV("DEBUG(%s): ion_size(%d), stride(%d), ", __FUNCTION__,priv_handle->size, priv_handle->stride);
1275
1276
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001277 for (plane_index=0 ; plane_index < v4l2_buf.length ; plane_index++) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001278 currentBuf.virt.extP[plane_index] = (char *)virtAddr[plane_index];
1279 v4l2_buf.m.planes[plane_index].length = currentBuf.size.extS[plane_index];
1280 ALOGV("DEBUG(%s): plane(%d): fd(%d) addr(%x), length(%d)",
1281 __FUNCTION__, plane_index, v4l2_buf.m.planes[plane_index].m.fd,
1282 (unsigned int)currentBuf.virt.extP[plane_index],
1283 v4l2_buf.m.planes[plane_index].length);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001284 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001285
1286 if (targetStreamParms->streamType == 0) {
1287 if (i < currentNode->buffers) {
1288 if (exynos_v4l2_qbuf(currentNode->fd, &v4l2_buf) < 0) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001289 ALOGE("ERR(%s): stream id(%d) exynos_v4l2_qbuf() fail fd(%d)",
1290 __FUNCTION__, stream_id, currentNode->fd);
1291 //return false;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001292 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001293 ALOGV("DEBUG(%s): stream id(%d) exynos_v4l2_qbuf() success fd(%d)",
1294 __FUNCTION__, stream_id, currentNode->fd);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001295 targetStreamParms->svcBufStatus[i] = REQUIRES_DQ_FROM_SVC;
1296 }
1297 else {
1298 targetStreamParms->svcBufStatus[i] = ON_SERVICE;
1299 }
1300 }
1301 else if (targetStreamParms->streamType == 1) {
1302 targetStreamParms->svcBufStatus[i] = ON_SERVICE;
1303 }
1304 targetStreamParms->svcBuffers[i] = currentBuf;
1305 targetStreamParms->svcBufHandle[i] = registeringBuffers[i];
1306 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001307 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001308 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001309 ALOGV("DEBUG(%s): calling streamon", __FUNCTION__);
1310 cam_int_streamon(&(targetStreamParms->node));
1311 ALOGV("DEBUG(%s): calling streamon END", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001312 ALOGV("DEBUG(%s): END registerStreamBuffers", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001313 return 0;
1314}
1315
1316int ExynosCameraHWInterface2::releaseStream(uint32_t stream_id)
1317{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001318 StreamThread *targetStream;
1319 ALOGV("DEBUG(%s):", __FUNCTION__);
1320
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001321 if (stream_id == 0) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001322 targetStream = (StreamThread*)(m_streamThreads[0].get());
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001323 m_scp_flushing = true;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001324 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001325 else if (stream_id == 1) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001326 targetStream = (StreamThread*)(m_streamThreads[1].get());
1327 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001328 else if (stream_id == 2 && m_recordingEnabled) {
1329 m_recordingEnabled = false;
1330 return 0;
1331 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001332 else {
1333 ALOGE("ERR:(%s): wrong stream id (%d)", __FUNCTION__, stream_id);
1334 return 1; // TODO : proper error code?
1335 }
1336
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001337 targetStream->m_releasing = true;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001338 targetStream->release();
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001339 while (targetStream->m_releasing)
1340 usleep(2000);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001341 targetStream->m_activated = false;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001342 ALOGV("DEBUG(%s): DONE", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001343 return 0;
1344}
1345
1346int ExynosCameraHWInterface2::allocateReprocessStream(
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001347 uint32_t width, uint32_t height, uint32_t format,
1348 const camera2_stream_in_ops_t *reprocess_stream_ops,
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001349 uint32_t *stream_id, uint32_t *consumer_usage, uint32_t *max_buffers)
1350{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001351 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001352 return 0;
1353}
1354
1355int ExynosCameraHWInterface2::releaseReprocessStream(uint32_t stream_id)
1356{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001357 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001358 return 0;
1359}
1360
1361int ExynosCameraHWInterface2::triggerAction(uint32_t trigger_id, int ext1, int ext2)
1362{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001363 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001364 return 0;
1365}
1366
1367int ExynosCameraHWInterface2::setNotifyCallback(camera2_notify_callback notify_cb, void *user)
1368{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001369 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001370 m_notifyCb = notify_cb;
1371 m_callbackCookie = user;
1372 return 0;
1373}
1374
1375int ExynosCameraHWInterface2::getMetadataVendorTagOps(vendor_tag_query_ops_t **ops)
1376{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001377 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001378 return 0;
1379}
1380
1381int ExynosCameraHWInterface2::dump(int fd)
1382{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001383 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001384 return 0;
1385}
1386
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001387void ExynosCameraHWInterface2::m_getAlignedYUVSize(int colorFormat, int w, int h, ExynosBuffer *buf)
1388{
1389 switch (colorFormat) {
1390 // 1p
1391 case V4L2_PIX_FMT_RGB565 :
1392 case V4L2_PIX_FMT_YUYV :
1393 case V4L2_PIX_FMT_UYVY :
1394 case V4L2_PIX_FMT_VYUY :
1395 case V4L2_PIX_FMT_YVYU :
1396 buf->size.extS[0] = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(colorFormat), w, h);
1397 buf->size.extS[1] = 0;
1398 buf->size.extS[2] = 0;
1399 break;
1400 // 2p
1401 case V4L2_PIX_FMT_NV12 :
1402 case V4L2_PIX_FMT_NV12T :
1403 case V4L2_PIX_FMT_NV21 :
1404 buf->size.extS[0] = ALIGN(w, 16) * ALIGN(h, 16);
1405 buf->size.extS[1] = ALIGN(w/2, 16) * ALIGN(h/2, 16);
1406 buf->size.extS[2] = 0;
1407 break;
1408 case V4L2_PIX_FMT_NV12M :
1409 case V4L2_PIX_FMT_NV12MT_16X16 :
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001410 case V4L2_PIX_FMT_NV21M:
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001411 buf->size.extS[0] = ALIGN(w, 16) * ALIGN(h, 16);
1412 buf->size.extS[1] = ALIGN(buf->size.extS[0] / 2, 256);
1413 buf->size.extS[2] = 0;
1414 break;
1415 case V4L2_PIX_FMT_NV16 :
1416 case V4L2_PIX_FMT_NV61 :
1417 buf->size.extS[0] = ALIGN(w, 16) * ALIGN(h, 16);
1418 buf->size.extS[1] = ALIGN(w, 16) * ALIGN(h, 16);
1419 buf->size.extS[2] = 0;
1420 break;
1421 // 3p
1422 case V4L2_PIX_FMT_YUV420 :
1423 case V4L2_PIX_FMT_YVU420 :
1424 buf->size.extS[0] = (w * h);
1425 buf->size.extS[1] = (w * h) >> 2;
1426 buf->size.extS[2] = (w * h) >> 2;
1427 break;
1428 case V4L2_PIX_FMT_YUV420M:
1429 case V4L2_PIX_FMT_YVU420M :
1430 case V4L2_PIX_FMT_YUV422P :
1431 buf->size.extS[0] = ALIGN(w, 32) * ALIGN(h, 16);
1432 buf->size.extS[1] = ALIGN(w/2, 16) * ALIGN(h/2, 8);
1433 buf->size.extS[2] = ALIGN(w/2, 16) * ALIGN(h/2, 8);
1434 break;
1435 default:
1436 ALOGE("ERR(%s):unmatched colorFormat(%d)", __FUNCTION__, colorFormat);
1437 return;
1438 break;
1439 }
1440}
1441
1442bool ExynosCameraHWInterface2::m_getRatioSize(int src_w, int src_h,
1443 int dst_w, int dst_h,
1444 int *crop_x, int *crop_y,
1445 int *crop_w, int *crop_h,
1446 int zoom)
1447{
1448 *crop_w = src_w;
1449 *crop_h = src_h;
1450
1451 if ( src_w != dst_w
1452 || src_h != dst_h) {
1453 float src_ratio = 1.0f;
1454 float dst_ratio = 1.0f;
1455
1456 // ex : 1024 / 768
1457 src_ratio = (float)src_w / (float)src_h;
1458
1459 // ex : 352 / 288
1460 dst_ratio = (float)dst_w / (float)dst_h;
1461
1462 if (dst_w * dst_h < src_w * src_h) {
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 } else {
1473 if (dst_ratio <= src_ratio) {
1474 // shrink w
1475 *crop_w = src_h * dst_ratio;
1476 *crop_h = src_h;
1477 } else {
1478 // shrink h
1479 *crop_w = src_w;
1480 *crop_h = src_w / dst_ratio;
1481 }
1482 }
1483 }
1484
1485 if (zoom != 0) {
1486 float zoomLevel = ((float)zoom + 10.0) / 10.0;
1487 *crop_w = (int)((float)*crop_w / zoomLevel);
1488 *crop_h = (int)((float)*crop_h / zoomLevel);
1489 }
1490
1491 #define CAMERA_CROP_WIDTH_RESTRAIN_NUM (0x2)
1492 unsigned int w_align = (*crop_w & (CAMERA_CROP_WIDTH_RESTRAIN_NUM - 1));
1493 if (w_align != 0) {
1494 if ( (CAMERA_CROP_WIDTH_RESTRAIN_NUM >> 1) <= w_align
1495 && *crop_w + (CAMERA_CROP_WIDTH_RESTRAIN_NUM - w_align) <= dst_w) {
1496 *crop_w += (CAMERA_CROP_WIDTH_RESTRAIN_NUM - w_align);
1497 }
1498 else
1499 *crop_w -= w_align;
1500 }
1501
1502 #define CAMERA_CROP_HEIGHT_RESTRAIN_NUM (0x2)
1503 unsigned int h_align = (*crop_h & (CAMERA_CROP_HEIGHT_RESTRAIN_NUM - 1));
1504 if (h_align != 0) {
1505 if ( (CAMERA_CROP_HEIGHT_RESTRAIN_NUM >> 1) <= h_align
1506 && *crop_h + (CAMERA_CROP_HEIGHT_RESTRAIN_NUM - h_align) <= dst_h) {
1507 *crop_h += (CAMERA_CROP_HEIGHT_RESTRAIN_NUM - h_align);
1508 }
1509 else
1510 *crop_h -= h_align;
1511 }
1512
1513 *crop_x = (src_w - *crop_w) >> 1;
1514 *crop_y = (src_h - *crop_h) >> 1;
1515
1516 if (*crop_x & (CAMERA_CROP_WIDTH_RESTRAIN_NUM >> 1))
1517 *crop_x -= 1;
1518
1519 if (*crop_y & (CAMERA_CROP_HEIGHT_RESTRAIN_NUM >> 1))
1520 *crop_y -= 1;
1521
1522 return true;
1523}
1524
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001525BayerBufManager::BayerBufManager()
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001526{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001527 ALOGV("DEBUG(%s): ", __FUNCTION__);
1528 for (int i = 0; i < NUM_BAYER_BUFFERS ; i++) {
1529 entries[i].status = BAYER_ON_HAL_EMPTY;
1530 entries[i].reqFrameCnt = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001531 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001532 sensorEnqueueHead = 0;
1533 sensorDequeueHead = 0;
1534 ispEnqueueHead = 0;
1535 ispDequeueHead = 0;
1536 numOnSensor = 0;
1537 numOnIsp = 0;
1538 numOnHalFilled = 0;
1539 numOnHalEmpty = NUM_BAYER_BUFFERS;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001540}
1541
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001542int BayerBufManager::GetIndexForSensorEnqueue()
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001543{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001544 int ret = 0;
1545 if (numOnHalEmpty == 0)
1546 ret = -1;
1547 else
1548 ret = sensorEnqueueHead;
1549 ALOGV("DEBUG(%s): returning (%d)", __FUNCTION__, ret);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001550 return ret;
1551}
1552
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001553int BayerBufManager::MarkSensorEnqueue(int index)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001554{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001555 ALOGV("DEBUG(%s) : BayerIndex[%d] ", __FUNCTION__, index);
1556
1557 // sanity check
1558 if (index != sensorEnqueueHead) {
1559 ALOGV("DEBUG(%s) : Abnormal BayerIndex[%d] - expected[%d]", __FUNCTION__, index, sensorEnqueueHead);
1560 return -1;
1561 }
1562 if (entries[index].status != BAYER_ON_HAL_EMPTY) {
1563 ALOGV("DEBUG(%s) : Abnormal status in BayerIndex[%d] = (%d) expected (%d)", __FUNCTION__,
1564 index, entries[index].status, BAYER_ON_HAL_EMPTY);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001565 return -1;
1566 }
1567
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001568 entries[index].status = BAYER_ON_SENSOR;
1569 entries[index].reqFrameCnt = 0;
1570 numOnHalEmpty--;
1571 numOnSensor++;
1572 sensorEnqueueHead = GetNextIndex(index);
1573 ALOGV("DEBUG(%s) END: HAL-e(%d) HAL-f(%d) Sensor(%d) ISP(%d) ",
1574 __FUNCTION__, numOnHalEmpty, numOnHalFilled, numOnSensor, numOnIsp);
1575 return 0;
1576}
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001577
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001578int BayerBufManager::MarkSensorDequeue(int index, int reqFrameCnt, nsecs_t *timeStamp)
1579{
1580 ALOGV("DEBUG(%s) : BayerIndex[%d] reqFrameCnt(%d)", __FUNCTION__, index, reqFrameCnt);
1581
1582 // sanity check
1583 if (index != sensorDequeueHead) {
1584 ALOGV("DEBUG(%s) : Abnormal BayerIndex[%d] - expected[%d]", __FUNCTION__, index, sensorDequeueHead);
1585 return -1;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001586 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001587 if (entries[index].status != BAYER_ON_SENSOR) {
1588 ALOGV("DEBUG(%s) : Abnormal status in BayerIndex[%d] = (%d) expected (%d)", __FUNCTION__,
1589 index, entries[index].status, BAYER_ON_SENSOR);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001590 return -1;
1591 }
1592
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001593 entries[index].status = BAYER_ON_HAL_FILLED;
1594 entries[index].reqFrameCnt = reqFrameCnt;
1595 entries[index].timeStamp = *timeStamp;
1596 numOnHalFilled++;
1597 numOnSensor--;
1598 sensorDequeueHead = GetNextIndex(index);
1599 ALOGV("DEBUG(%s) END: HAL-e(%d) HAL-f(%d) Sensor(%d) ISP(%d) ",
1600 __FUNCTION__, numOnHalEmpty, numOnHalFilled, numOnSensor, numOnIsp);
1601 return 0;
1602}
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001603
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001604int BayerBufManager::GetIndexForIspEnqueue(int *reqFrameCnt)
1605{
1606 int ret = 0;
1607 if (numOnHalFilled == 0)
1608 ret = -1;
1609 else {
1610 *reqFrameCnt = entries[ispEnqueueHead].reqFrameCnt;
1611 ret = ispEnqueueHead;
1612 }
1613 ALOGV("DEBUG(%s): returning BayerIndex[%d]", __FUNCTION__, ret);
1614 return ret;
1615}
1616
1617int BayerBufManager::GetIndexForIspDequeue(int *reqFrameCnt)
1618{
1619 int ret = 0;
1620 if (numOnIsp == 0)
1621 ret = -1;
1622 else {
1623 *reqFrameCnt = entries[ispDequeueHead].reqFrameCnt;
1624 ret = ispDequeueHead;
1625 }
1626 ALOGV("DEBUG(%s): returning BayerIndex[%d]", __FUNCTION__, ret);
1627 return ret;
1628}
1629
1630int BayerBufManager::MarkIspEnqueue(int index)
1631{
1632 ALOGV("DEBUG(%s) : BayerIndex[%d] ", __FUNCTION__, index);
1633
1634 // sanity check
1635 if (index != ispEnqueueHead) {
1636 ALOGV("DEBUG(%s) : Abnormal BayerIndex[%d] - expected[%d]", __FUNCTION__, index, ispEnqueueHead);
1637 return -1;
1638 }
1639 if (entries[index].status != BAYER_ON_HAL_FILLED) {
1640 ALOGV("DEBUG(%s) : Abnormal status in BayerIndex[%d] = (%d) expected (%d)", __FUNCTION__,
1641 index, entries[index].status, BAYER_ON_HAL_FILLED);
1642 return -1;
1643 }
1644
1645 entries[index].status = BAYER_ON_ISP;
1646 numOnHalFilled--;
1647 numOnIsp++;
1648 ispEnqueueHead = GetNextIndex(index);
1649 ALOGV("DEBUG(%s) END: HAL-e(%d) HAL-f(%d) Sensor(%d) ISP(%d) ",
1650 __FUNCTION__, numOnHalEmpty, numOnHalFilled, numOnSensor, numOnIsp);
1651 return 0;
1652}
1653
1654int BayerBufManager::MarkIspDequeue(int index)
1655{
1656 ALOGV("DEBUG(%s) : BayerIndex[%d]", __FUNCTION__, index);
1657
1658 // sanity check
1659 if (index != ispDequeueHead) {
1660 ALOGV("DEBUG(%s) : Abnormal BayerIndex[%d] - expected[%d]", __FUNCTION__, index, ispDequeueHead);
1661 return -1;
1662 }
1663 if (entries[index].status != BAYER_ON_ISP) {
1664 ALOGV("DEBUG(%s) : Abnormal status in BayerIndex[%d] = (%d) expected (%d)", __FUNCTION__,
1665 index, entries[index].status, BAYER_ON_ISP);
1666 return -1;
1667 }
1668
1669 entries[index].status = BAYER_ON_HAL_EMPTY;
1670 entries[index].reqFrameCnt = 0;
1671 numOnHalEmpty++;
1672 numOnIsp--;
1673 ispDequeueHead = GetNextIndex(index);
1674 ALOGV("DEBUG(%s) END: HAL-e(%d) HAL-f(%d) Sensor(%d) ISP(%d) ",
1675 __FUNCTION__, numOnHalEmpty, numOnHalFilled, numOnSensor, numOnIsp);
1676 return 0;
1677}
1678
1679int BayerBufManager::GetNumOnSensor()
1680{
1681 return numOnSensor;
1682}
1683
1684int BayerBufManager::GetNumOnHalFilled()
1685{
1686 return numOnHalFilled;
1687}
1688
1689int BayerBufManager::GetNumOnIsp()
1690{
1691 return numOnIsp;
1692}
1693
1694int BayerBufManager::GetNextIndex(int index)
1695{
1696 index++;
1697 if (index >= NUM_BAYER_BUFFERS)
1698 index = 0;
1699
1700 return index;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001701}
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001702
1703void ExynosCameraHWInterface2::m_mainThreadFunc(SignalDrivenThread * self)
1704{
1705 camera_metadata_t *currentRequest = NULL;
1706 camera_metadata_t *currentFrame = NULL;
1707 size_t numEntries = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001708 size_t frameSize = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001709 camera_metadata_t * preparedFrame = NULL;
1710 camera_metadata_t *deregisteredRequest = NULL;
1711 uint32_t currentSignal = self->GetProcessingSignal();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001712 MainThread * selfThread = ((MainThread*)self);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001713 int res = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001714
1715 ALOGV("DEBUG(%s): m_mainThreadFunc (%x)", __FUNCTION__, currentSignal);
1716
1717 if (currentSignal & SIGNAL_THREAD_RELEASE) {
1718 ALOGV("DEBUG(%s): processing SIGNAL_THREAD_RELEASE", __FUNCTION__);
1719
1720 ALOGV("DEBUG(%s): processing SIGNAL_THREAD_RELEASE DONE", __FUNCTION__);
1721 selfThread->SetSignal(SIGNAL_THREAD_TERMINATE);
1722 return;
1723 }
1724
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001725 if (currentSignal & SIGNAL_MAIN_REQ_Q_NOT_EMPTY) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001726 ALOGV("DEBUG(%s): MainThread processing SIGNAL_MAIN_REQ_Q_NOT_EMPTY", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001727 if (m_requestManager->IsRequestQueueFull()==false
1728 && m_requestManager->GetNumEntries()<NUM_MAX_DEQUEUED_REQUEST) {
1729 m_requestQueueOps->dequeue_request(m_requestQueueOps, &currentRequest);
1730 if (NULL == currentRequest) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001731 ALOGV("DEBUG(%s): dequeue_request returned NULL ", __FUNCTION__);
1732 m_isRequestQueueNull = true;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001733 }
1734 else {
1735 m_requestManager->RegisterRequest(currentRequest);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001736
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001737 m_numOfRemainingReqInSvc = m_requestQueueOps->request_count(m_requestQueueOps);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001738 ALOGV("DEBUG(%s): remaining req cnt (%d)", __FUNCTION__, m_numOfRemainingReqInSvc);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001739 if (m_requestManager->IsRequestQueueFull()==false
1740 && m_requestManager->GetNumEntries()<NUM_MAX_DEQUEUED_REQUEST)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001741 selfThread->SetSignal(SIGNAL_MAIN_REQ_Q_NOT_EMPTY); // dequeue repeatedly
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001742
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001743 m_sensorThread->SetSignal(SIGNAL_SENSOR_START_REQ_PROCESSING);
1744 }
1745 }
1746 else {
1747 m_isRequestQueuePending = true;
1748 }
1749 }
1750
1751 if (currentSignal & SIGNAL_MAIN_STREAM_OUTPUT_DONE) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001752 ALOGV("DEBUG(%s): MainThread processing SIGNAL_MAIN_STREAM_OUTPUT_DONE", __FUNCTION__);
1753 /*while (1)*/ {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001754 m_requestManager->PrepareFrame(&numEntries, &frameSize, &preparedFrame);
1755 m_requestManager->DeregisterRequest(&deregisteredRequest);
1756 m_requestQueueOps->free_request(m_requestQueueOps, deregisteredRequest);
1757 m_frameQueueOps->dequeue_frame(m_frameQueueOps, numEntries, frameSize, &currentFrame);
1758 if (currentFrame==NULL) {
1759 ALOGD("DBG(%s): frame dequeue returned NULL",__FUNCTION__ );
1760 }
1761 else {
1762 ALOGV("DEBUG(%s): frame dequeue done. numEntries(%d) frameSize(%d)",__FUNCTION__ , numEntries,frameSize);
1763 }
1764 res = append_camera_metadata(currentFrame, preparedFrame);
1765 if (res==0) {
1766 ALOGV("DEBUG(%s): frame metadata append success",__FUNCTION__);
1767 m_frameQueueOps->enqueue_frame(m_frameQueueOps, currentFrame);
1768 }
1769 else {
1770 ALOGE("ERR(%s): frame metadata append fail (%d)",__FUNCTION__, res);
1771 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001772 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001773 if (!m_isRequestQueueNull) {
1774 selfThread->SetSignal(SIGNAL_MAIN_REQ_Q_NOT_EMPTY);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001775 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001776
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001777 if (getInProgressCount()>0) {
1778 ALOGV("DEBUG(%s): STREAM_OUTPUT_DONE and signalling REQ_PROCESSING",__FUNCTION__);
1779 m_sensorThread->SetSignal(SIGNAL_SENSOR_START_REQ_PROCESSING);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001780 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001781 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001782 ALOGV("DEBUG(%s): MainThread Exit", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001783 return;
1784}
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001785
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001786void ExynosCameraHWInterface2::m_sensorThreadInitialize(SignalDrivenThread * self)
1787{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001788 ALOGV("DEBUG(%s): ", __FUNCTION__ );
1789 SensorThread * selfThread = ((SensorThread*)self);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001790 char node_name[30];
1791 int fd = 0;
1792 int i =0, j=0;
1793
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001794 if(m_cameraId == 0)
1795 m_camera_info.sensor_id = SENSOR_NAME_S5K4E5;
1796 else
1797 m_camera_info.sensor_id = SENSOR_NAME_S5K6A3;
1798
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001799 memset(&m_camera_info.dummy_shot, 0x00, sizeof(struct camera2_shot_ext));
1800 m_camera_info.dummy_shot.shot.ctl.request.metadataMode = METADATA_MODE_FULL;
1801 m_camera_info.dummy_shot.shot.magicNumber = 0x23456789;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001802
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001803 m_camera_info.dummy_shot.dis_bypass = 1;
1804 m_camera_info.dummy_shot.dnr_bypass = 1;
1805
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001806 /*sensor setting*/
1807 m_camera_info.dummy_shot.shot.ctl.sensor.exposureTime = 0;
1808 m_camera_info.dummy_shot.shot.ctl.sensor.frameDuration = 0;
1809 m_camera_info.dummy_shot.shot.ctl.sensor.sensitivity = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001810
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001811 m_camera_info.dummy_shot.shot.ctl.scaler.cropRegion[0] = 0;
1812 m_camera_info.dummy_shot.shot.ctl.scaler.cropRegion[1] = 0;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001813 //m_camera_info.dummy_shot.shot.ctl.scaler.cropRegion[2] = 1920;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001814
1815 /*request setting*/
1816 m_camera_info.dummy_shot.request_sensor = 1;
1817 m_camera_info.dummy_shot.request_scc = 0;
1818 m_camera_info.dummy_shot.request_scp = 0;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001819 m_camera_info.dummy_shot.shot.ctl.request.outputStreams[0] = 0;
1820 m_camera_info.dummy_shot.shot.ctl.request.outputStreams[1] = 0;
1821 m_camera_info.dummy_shot.shot.ctl.request.outputStreams[2] = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001822
1823 /*sensor init*/
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001824 memset(&node_name, 0x00, sizeof(char[30]));
1825 sprintf(node_name, "%s%d", NODE_PREFIX, 40);
1826 fd = exynos_v4l2_open(node_name, O_RDWR, 0);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001827
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001828 if (fd < 0) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001829 ALOGE("ERR(%s): failed to open sensor video node (%s) fd (%d)", __FUNCTION__,node_name, fd);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001830 }
1831 else {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001832 ALOGV("DEBUG(%s): sensor video node opened(%s) fd (%d)", __FUNCTION__,node_name, fd);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001833 }
1834 m_camera_info.sensor.fd = fd;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001835
1836 m_camera_info.sensor.width = getSensorOutputSizeX(m_cameraId);
1837 m_camera_info.sensor.height = getSensorOutputSizeY(m_cameraId);
1838
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001839 m_camera_info.sensor.format = V4L2_PIX_FMT_SBGGR16;
1840 m_camera_info.sensor.planes = 2;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001841 m_camera_info.sensor.buffers = NUM_BAYER_BUFFERS;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001842 m_camera_info.sensor.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
Alex Ray24231222012-06-27 15:18:15 -07001843 m_camera_info.sensor.memory = V4L2_MEMORY_DMABUF;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07001844 m_camera_info.sensor.ionClient = m_ionCameraClient;
1845
1846 for(i = 0; i < m_camera_info.sensor.buffers; i++){
1847 initCameraMemory(&m_camera_info.sensor.buffer[i], m_camera_info.sensor.planes);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001848 m_camera_info.sensor.buffer[i].size.extS[0] = m_camera_info.sensor.width*m_camera_info.sensor.height*2;
1849 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 -07001850 allocCameraMemory(m_camera_info.sensor.ionClient, &m_camera_info.sensor.buffer[i], m_camera_info.sensor.planes);
1851 }
1852
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001853 m_initFlag1 = true;
1854
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001855
1856 while (!m_initFlag2) // temp
1857 usleep(100000);
1858 ALOGV("DEBUG(%s): END of SensorThreadInitialize ", __FUNCTION__);
1859 return;
1860}
1861
1862
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001863void ExynosCameraHWInterface2::DumpInfoWithShot(struct camera2_shot_ext * shot_ext)
1864{
1865 ALOGV("#### common Section");
1866 ALOGV("#### magic(%x) ",
1867 shot_ext->shot.magicNumber);
1868 ALOGV("#### ctl Section");
1869 ALOGV("#### metamode(%d) exposureTime(%lld) duration(%lld) ISO(%d) ",
1870 shot_ext->shot.ctl.request.metadataMode,
1871 shot_ext->shot.ctl.sensor.exposureTime,
1872 shot_ext->shot.ctl.sensor.frameDuration,
1873 shot_ext->shot.ctl.sensor.sensitivity);
1874
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001875 ALOGV("#### OutputStream Sensor(%d) SCP(%d) SCC(%d) pv(%d) rec(%d)",
1876 shot_ext->request_sensor, shot_ext->request_scp, shot_ext->request_scc,
1877 shot_ext->shot.ctl.request.outputStreams[0],
1878 shot_ext->shot.ctl.request.outputStreams[2]);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001879
1880 ALOGV("#### DM Section");
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001881 ALOGV("#### metamode(%d) exposureTime(%lld) duration(%lld) ISO(%d) timestamp(%lld)",
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001882 shot_ext->shot.dm.request.metadataMode,
1883 shot_ext->shot.dm.sensor.exposureTime,
1884 shot_ext->shot.dm.sensor.frameDuration,
1885 shot_ext->shot.dm.sensor.sensitivity,
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001886// shot_ext->shot.dm.sensor.frameCount,
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001887 shot_ext->shot.dm.sensor.timeStamp);
1888}
1889
1890void ExynosCameraHWInterface2::m_sensorThreadFunc(SignalDrivenThread * self)
1891{
1892 uint32_t currentSignal = self->GetProcessingSignal();
1893 SensorThread * selfThread = ((SensorThread*)self);
1894 int index;
1895 status_t res;
1896 nsecs_t frameTime;
1897 int bayersOnSensor = 0, bayersOnIsp = 0;
1898 ALOGV("DEBUG(%s): m_sensorThreadFunc (%x)", __FUNCTION__, currentSignal);
1899
1900 if (currentSignal & SIGNAL_THREAD_RELEASE) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001901 ALOGD("(%s): ENTER processing SIGNAL_THREAD_RELEASE", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001902
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001903#if 0 // TODO
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001904 for (int i = 0 ; i < NUM_BAYER_BUFFERS ; i++) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001905 ALOGV("DEBUG(%s):### BayerIndex[%d] Status (%d)", __FUNCTION__, i, m_bayerBufStatus[i]);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001906 if (m_bayerBufStatus[i]==BAYER_ON_SENSOR) {
1907 bayersOnSensor++;
1908 }
1909 else if (m_bayerBufStatus[i]==BAYER_ON_ISP) {
1910 bayersOnIsp++;
1911 }
1912 }
1913 for (int i = 0 ; i < bayersOnSensor ; i++) {
1914 index = cam_int_dqbuf(&(m_camera_info.sensor));
1915 ALOGV("DEBUG(%s):### sensor dqbuf done index(%d)", __FUNCTION__, index);
1916 m_bayerBufStatus[index] = BAYER_ON_HAL_EMPTY;
1917 }
1918 for (int i = 0 ; i < bayersOnIsp ; i++) {
1919 index = cam_int_dqbuf(&(m_camera_info.isp));
1920 ALOGV("DEBUG(%s):### isp dqbuf done index(%d)", __FUNCTION__, index);
1921 m_bayerBufStatus[index] = BAYER_ON_HAL_EMPTY;
1922 }
1923
1924 for (int i = 0 ; i < NUM_BAYER_BUFFERS ; i++) {
1925 ALOGV("DEBUG(%s):### Bayer Buf[%d] Status (%d)", __FUNCTION__, i, m_bayerBufStatus[i]);
1926 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001927#endif
1928 ALOGV("(%s): calling sensor streamoff", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001929 cam_int_streamoff(&(m_camera_info.sensor));
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001930 ALOGV("(%s): calling sensor streamoff done", __FUNCTION__);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001931
1932 m_camera_info.sensor.buffers = 0;
1933 ALOGV("DEBUG(%s): sensor calling reqbuf 0 ", __FUNCTION__);
1934 cam_int_reqbufs(&(m_camera_info.sensor));
1935 ALOGV("DEBUG(%s): sensor calling reqbuf 0 done", __FUNCTION__);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001936
1937 ALOGV("(%s): calling ISP streamoff", __FUNCTION__);
1938 isp_int_streamoff(&(m_camera_info.isp));
1939 ALOGV("(%s): calling ISP streamoff done", __FUNCTION__);
1940
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001941 m_camera_info.isp.buffers = 0;
1942 ALOGV("DEBUG(%s): isp calling reqbuf 0 ", __FUNCTION__);
1943 cam_int_reqbufs(&(m_camera_info.isp));
1944 ALOGV("DEBUG(%s): isp calling reqbuf 0 done", __FUNCTION__);
1945
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001946 exynos_v4l2_s_ctrl(m_camera_info.sensor.fd, V4L2_CID_IS_S_STREAM, IS_DISABLE_STREAM);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001947
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001948 ALOGD("(%s): EXIT processing SIGNAL_THREAD_RELEASE", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001949 selfThread->SetSignal(SIGNAL_THREAD_TERMINATE);
1950 return;
1951 }
1952
1953 if (currentSignal & SIGNAL_SENSOR_START_REQ_PROCESSING)
1954 {
1955 ALOGV("DEBUG(%s): SensorThread processing SIGNAL_SENSOR_START_REQ_PROCESSING", __FUNCTION__);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001956 int targetStreamIndex = 0, i=0;
1957 int matchedFrameCnt, processingReqIndex;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001958 struct camera2_shot_ext *shot_ext;
1959 if (!m_isSensorStarted)
1960 {
1961 m_isSensorStarted = true;
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001962 ALOGD("(%s): calling preview streamon", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001963 cam_int_streamon(&(m_streamThreads[0]->m_parameters.node));
Sungjoong Kangb5237e62012-07-27 07:39:05 -07001964 ALOGD("(%s): calling isp streamon done", __FUNCTION__);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001965 for (i = 0; i < m_camera_info.isp.buffers; i++) {
1966 ALOGV("DEBUG(%s): isp initial QBUF [%d]", __FUNCTION__, i);
1967 cam_int_qbuf(&(m_camera_info.isp), i);
1968 }
1969
1970 cam_int_streamon(&(m_camera_info.isp));
1971
1972 for (i = 0; i < m_camera_info.isp.buffers; i++) {
1973 ALOGV("DEBUG(%s): isp initial DQBUF [%d]", __FUNCTION__, i);
1974 cam_int_dqbuf(&(m_camera_info.isp));
1975 }
1976
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001977 ALOGV("DEBUG(%s): calling isp sctrl done", __FUNCTION__);
1978 exynos_v4l2_s_ctrl(m_camera_info.sensor.fd, V4L2_CID_IS_S_STREAM, IS_ENABLE_STREAM);
1979 ALOGV("DEBUG(%s): calling sensor sctrl done", __FUNCTION__);
1980
1981 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001982
Alex Ray3f0357b2012-07-30 16:42:12 -07001983 ALOGV("### Sensor DQBUF start");
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09001984 index = cam_int_dqbuf(&(m_camera_info.sensor));
1985 frameTime = systemTime();
Alex Ray3f0357b2012-07-30 16:42:12 -07001986 ALOGV("### Sensor DQBUF done BayerIndex(%d)", index);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09001987 bool wait = false;
1988 shot_ext = (struct camera2_shot_ext *)(m_camera_info.sensor.buffer[index].virt.extP[1]);
1989 matchedFrameCnt = m_requestManager->FindFrameCnt(shot_ext);
Alex Ray3f0357b2012-07-30 16:42:12 -07001990 ALOGV("### Matched(%d) last(%d)", matchedFrameCnt, lastFrameCnt);
Sungjoong Kanga07cbd92012-07-27 12:03:29 -07001991#if 1
1992 if (matchedFrameCnt != -1) {
1993 while (matchedFrameCnt == lastFrameCnt) {
1994 m_BayerManager->MarkSensorDequeue(index, -1, &frameTime);
Alex Ray3f0357b2012-07-30 16:42:12 -07001995 ALOGV("### Sensor DQBUF start");
Sungjoong Kanga07cbd92012-07-27 12:03:29 -07001996 index = cam_int_dqbuf(&(m_camera_info.sensor));
1997 frameTime = systemTime();
Alex Ray3f0357b2012-07-30 16:42:12 -07001998 ALOGV("### Sensor DQBUF done BayerIndex(%d)", index);
Sungjoong Kanga07cbd92012-07-27 12:03:29 -07001999 bool wait = false;
2000 shot_ext = (struct camera2_shot_ext *)(m_camera_info.sensor.buffer[index].virt.extP[1]);
2001 matchedFrameCnt = m_requestManager->FindFrameCnt(shot_ext);
Alex Ray3f0357b2012-07-30 16:42:12 -07002002 ALOGV("### Matched(%d) last(%d)", matchedFrameCnt, lastFrameCnt);
Sungjoong Kanga07cbd92012-07-27 12:03:29 -07002003 }
2004 lastFrameCnt = matchedFrameCnt;
2005 }
2006#else
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002007 if (m_sensor_drop) {
2008 matchedFrameCnt = -1;
2009 m_sensor_drop = false;
2010 }
2011 else if (matchedFrameCnt != -1) {
2012 if (matchedFrameCnt == lastFrameCnt) {
2013 m_sensor_drop = true;
2014 matchedFrameCnt++;
2015 }
2016 lastFrameCnt = matchedFrameCnt;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002017 m_scp_closing = false;
2018 m_scp_closed = false;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002019 }
Sungjoong Kanga07cbd92012-07-27 12:03:29 -07002020#endif
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002021 m_BayerManager->MarkSensorDequeue(index, matchedFrameCnt, &frameTime);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002022
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002023 m_requestManager->RegisterTimestamp(matchedFrameCnt, &frameTime);
Alex Ray386436c2012-07-30 16:55:15 -07002024 ALOGV("### Sensor DQed BayerIndex[%d] passing to ISP. frameCnt(%d) timestamp(%lld)",
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002025 index, matchedFrameCnt, frameTime);
2026
2027 if (!(m_ispThread.get()))
2028 return;
2029
2030 m_ispThread->SetSignal(SIGNAL_ISP_START_BAYER_INPUT);
2031
2032 while (m_BayerManager->GetNumOnSensor() <= NUM_SENSOR_QBUF) {
2033
2034 index = m_BayerManager->GetIndexForSensorEnqueue();
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002035 if (index == -1) {
2036 ALOGE("ERR(%s) No free Bayer buffer", __FUNCTION__);
2037 break;
2038 }
2039 processingReqIndex = m_requestManager->MarkProcessingRequest(&(m_camera_info.sensor.buffer[index]));
2040
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002041 shot_ext = (struct camera2_shot_ext *)(m_camera_info.sensor.buffer[index].virt.extP[1]);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002042 if (processingReqIndex == -1) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002043 ALOGV("DEBUG(%s) req underrun => inserting bubble to BayerIndex(%d)", __FUNCTION__, index);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002044 memcpy(shot_ext, &(m_camera_info.dummy_shot), sizeof(struct camera2_shot_ext));
2045 }
2046
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002047 m_BayerManager->MarkSensorEnqueue(index);
2048 if (m_scp_closing || m_scp_closed) {
2049 ALOGV("(%s): SCP_CLOSING(%d) SCP_CLOSED(%d)", __FUNCTION__, m_scp_closing, m_scp_closed);
2050 shot_ext->request_scc = 0;
2051 shot_ext->request_scp = 0;
2052 shot_ext->request_sensor = 0;
2053 }
Alex Ray386436c2012-07-30 16:55:15 -07002054 ALOGV("### Sensor QBUF start BayerIndex[%d]", index);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002055 cam_int_qbuf(&(m_camera_info.sensor), index);
Alex Ray386436c2012-07-30 16:55:15 -07002056 ALOGV("### Sensor QBUF done");
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002057 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002058 if (!m_closing){
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002059 selfThread->SetSignal(SIGNAL_SENSOR_START_REQ_PROCESSING);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002060 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002061 /*if (wait) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002062 ALOGE("###waiting###");
2063 usleep(20000);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002064 }*/
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002065 return;
2066 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002067 return;
2068}
2069
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002070void ExynosCameraHWInterface2::m_ispThreadInitialize(SignalDrivenThread * self)
2071{
2072 ALOGV("DEBUG(%s): ", __FUNCTION__ );
2073 IspThread * selfThread = ((IspThread*)self);
2074 char node_name[30];
2075 int fd = 0;
2076 int i =0, j=0;
2077
2078
2079 while (!m_initFlag1) //temp
2080 usleep(100000);
2081
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002082 /*isp init*/
2083 memset(&node_name, 0x00, sizeof(char[30]));
2084 sprintf(node_name, "%s%d", NODE_PREFIX, 41);
2085 fd = exynos_v4l2_open(node_name, O_RDWR, 0);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002086
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002087 if (fd < 0) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002088 ALOGE("ERR(%s): failed to open isp video node (%s) fd (%d)", __FUNCTION__,node_name, fd);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002089 }
2090 else {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002091 ALOGV("DEBUG(%s): isp video node opened(%s) fd (%d)", __FUNCTION__,node_name, fd);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002092 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002093 m_camera_info.isp.fd = fd;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002094
2095 m_camera_info.isp.width = m_camera_info.sensor.width;
2096 m_camera_info.isp.height = m_camera_info.sensor.height;
2097 m_camera_info.isp.format = m_camera_info.sensor.format;
2098 m_camera_info.isp.planes = m_camera_info.sensor.planes;
2099 m_camera_info.isp.buffers = m_camera_info.sensor.buffers;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002100 m_camera_info.isp.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Alex Ray24231222012-06-27 15:18:15 -07002101 m_camera_info.isp.memory = V4L2_MEMORY_DMABUF;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002102
2103 for(i = 0; i < m_camera_info.isp.buffers; i++){
2104 initCameraMemory(&m_camera_info.isp.buffer[i], m_camera_info.isp.planes);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002105 m_camera_info.isp.buffer[i].size.extS[0] = m_camera_info.sensor.buffer[i].size.extS[0];
2106 m_camera_info.isp.buffer[i].size.extS[1] = m_camera_info.sensor.buffer[i].size.extS[1];
2107 m_camera_info.isp.buffer[i].fd.extFd[0] = m_camera_info.sensor.buffer[i].fd.extFd[0];
2108 m_camera_info.isp.buffer[i].fd.extFd[1] = m_camera_info.sensor.buffer[i].fd.extFd[1];
2109 m_camera_info.isp.buffer[i].virt.extP[0] = m_camera_info.sensor.buffer[i].virt.extP[0];
2110 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 -07002111 };
2112
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002113 cam_int_s_input(&(m_camera_info.isp), m_camera_info.sensor_id);
2114 cam_int_s_fmt(&(m_camera_info.isp));
2115 ALOGV("DEBUG(%s): isp calling reqbuf", __FUNCTION__);
2116 cam_int_reqbufs(&(m_camera_info.isp));
2117 ALOGV("DEBUG(%s): isp calling querybuf", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002118 ALOGV("DEBUG(%s): isp mem alloc done", __FUNCTION__);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002119
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002120 cam_int_s_input(&(m_camera_info.sensor), m_camera_info.sensor_id);
2121 ALOGV("DEBUG(%s): sensor s_input done", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002122 if (cam_int_s_fmt(&(m_camera_info.sensor))< 0) {
2123 ALOGE("ERR(%s): sensor s_fmt fail", __FUNCTION__);
2124 }
2125 ALOGV("DEBUG(%s): sensor s_fmt done", __FUNCTION__);
2126 cam_int_reqbufs(&(m_camera_info.sensor));
2127 ALOGV("DEBUG(%s): sensor reqbuf done", __FUNCTION__);
2128 for (i = 0; i < m_camera_info.sensor.buffers; i++) {
2129 ALOGV("DEBUG(%s): sensor initial QBUF [%d]", __FUNCTION__, i);
2130 memcpy( m_camera_info.sensor.buffer[i].virt.extP[1], &(m_camera_info.dummy_shot),
2131 sizeof(struct camera2_shot_ext));
2132 m_camera_info.dummy_shot.shot.ctl.sensor.frameDuration = 33*1000*1000; // apply from frame #1
2133
2134 cam_int_qbuf(&(m_camera_info.sensor), i);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002135 m_BayerManager->MarkSensorEnqueue(i);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002136 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002137 ALOGE("== stream_on :: m_camera_info.sensor");
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002138 cam_int_streamon(&(m_camera_info.sensor));
2139
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002140
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002141
2142/*capture init*/
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002143 memset(&node_name, 0x00, sizeof(char[30]));
2144 sprintf(node_name, "%s%d", NODE_PREFIX, 42);
2145 fd = exynos_v4l2_open(node_name, O_RDWR, 0);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002146
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002147 if (fd < 0) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002148 ALOGE("ERR(%s): failed to open capture video node (%s) fd (%d)", __FUNCTION__,node_name, fd);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002149 }
2150 else {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002151 ALOGV("DEBUG(%s): capture video node opened(%s) fd (%d)", __FUNCTION__,node_name, fd);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002152 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002153 m_camera_info.capture.fd = fd;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002154
2155 m_camera_info.capture.width = getSccOutputSizeX(m_cameraId);
2156 m_camera_info.capture.height = getSccOutputSizeY(m_cameraId);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002157 m_camera_info.capture.format = V4L2_PIX_FMT_YUYV;
2158 m_camera_info.capture.planes = 1;
2159 m_camera_info.capture.buffers = 8;
2160 m_camera_info.capture.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
Alex Ray24231222012-06-27 15:18:15 -07002161 m_camera_info.capture.memory = V4L2_MEMORY_DMABUF;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002162 m_camera_info.capture.ionClient = m_ionCameraClient;
2163
2164 for(i = 0; i < m_camera_info.capture.buffers; i++){
2165 initCameraMemory(&m_camera_info.capture.buffer[i], m_camera_info.capture.planes);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002166 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 -07002167 allocCameraMemory(m_camera_info.capture.ionClient, &m_camera_info.capture.buffer[i], m_camera_info.capture.planes);
2168 }
2169
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002170 cam_int_s_input(&(m_camera_info.capture), m_camera_info.sensor_id);
2171 cam_int_s_fmt(&(m_camera_info.capture));
2172 ALOGV("DEBUG(%s): capture calling reqbuf", __FUNCTION__);
2173 cam_int_reqbufs(&(m_camera_info.capture));
2174 ALOGV("DEBUG(%s): capture calling querybuf", __FUNCTION__);
2175
2176 for (i = 0; i < m_camera_info.capture.buffers; i++) {
2177 ALOGV("DEBUG(%s): capture initial QBUF [%d]", __FUNCTION__, i);
2178 cam_int_qbuf(&(m_camera_info.capture), i);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002179 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002180
2181 ALOGE("== stream_on :: m_camera_info.capture");
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002182 cam_int_streamon(&(m_camera_info.capture));
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002183
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002184 m_initFlag2 = true;
2185 ALOGV("DEBUG(%s): END of IspThreadInitialize ", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002186 return;
2187}
2188
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002189
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002190void ExynosCameraHWInterface2::m_ispThreadFunc(SignalDrivenThread * self)
2191{
2192 uint32_t currentSignal = self->GetProcessingSignal();
2193 IspThread * selfThread = ((IspThread*)self);
2194 int index;
2195 status_t res;
2196 ALOGV("DEBUG(%s): m_ispThreadFunc (%x)", __FUNCTION__, currentSignal);
2197
2198 if (currentSignal & SIGNAL_THREAD_RELEASE) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002199 ALOGD("(%s): ENTER processing SIGNAL_THREAD_RELEASE", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002200
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002201 ALOGV("(%s): calling capture streamoff", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002202 cam_int_streamoff(&(m_camera_info.capture));
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002203 ALOGV("(%s): calling capture streamoff done", __FUNCTION__);
2204
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002205 m_camera_info.capture.buffers = 0;
2206 ALOGV("DEBUG(%s): capture calling reqbuf 0 ", __FUNCTION__);
2207 cam_int_reqbufs(&(m_camera_info.capture));
2208 ALOGV("DEBUG(%s): capture calling reqbuf 0 done", __FUNCTION__);
2209
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002210 ALOGD("(%s): EXIT processing SIGNAL_THREAD_RELEASE ", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002211 selfThread->SetSignal(SIGNAL_THREAD_TERMINATE);
2212 return;
2213 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002214
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002215 if (currentSignal & SIGNAL_ISP_START_BAYER_INPUT)
2216 {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002217 struct camera2_shot_ext *shot_ext;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002218 int bayerIndexToEnqueue = 0;
2219 int processingFrameCnt = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002220
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002221 ALOGV("DEBUG(%s): IspThread processing SIGNAL_ISP_START_BAYER_INPUT", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002222
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002223 bayerIndexToEnqueue = m_BayerManager->GetIndexForIspEnqueue(&processingFrameCnt);
2224 shot_ext = (struct camera2_shot_ext *)(m_camera_info.sensor.buffer[bayerIndexToEnqueue].virt.extP[1]);
2225
2226 ALOGV("### isp QBUF start bayerIndex[%d] for frameCnt(%d)", bayerIndexToEnqueue, processingFrameCnt);
2227
2228 if (processingFrameCnt != -1) {
2229 ALOGV("### writing output stream info");
2230 m_requestManager->UpdateOutputStreamInfo(shot_ext, processingFrameCnt);
2231 DumpInfoWithShot(shot_ext);
2232 }
2233 else {
2234 memcpy(shot_ext, &(m_camera_info.dummy_shot), sizeof(struct camera2_shot_ext));
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002235 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002236 if (m_scp_flushing) {
2237 shot_ext->request_scp = 1;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002238 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002239 if (m_scp_closing || m_scp_closed) {
2240 ALOGV("(%s): SCP_CLOSING(%d) SCP_CLOSED(%d)", __FUNCTION__, m_scp_closing, m_scp_closed);
2241 shot_ext->request_scc = 0;
2242 shot_ext->request_scp = 0;
2243 shot_ext->request_sensor = 0;
2244 }
Sungjoong Kanga07cbd92012-07-27 12:03:29 -07002245 //if (m_sensor_drop)
2246 // usleep(25000);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002247 cam_int_qbuf(&(m_camera_info.isp), bayerIndexToEnqueue);
2248 ALOGV("### isp QBUF done bayerIndex[%d] scp(%d)", bayerIndexToEnqueue, shot_ext->request_scp);
2249 m_BayerManager->MarkIspEnqueue(bayerIndexToEnqueue);
2250
2251 if (m_BayerManager->GetNumOnHalFilled() != 0) {
2252 // input has priority
2253 selfThread->SetSignal(SIGNAL_ISP_START_BAYER_INPUT);
2254 return;
2255 }
2256 else {
2257 selfThread->SetSignal(SIGNAL_ISP_START_BAYER_DEQUEUE);
2258 }
2259 }
2260
2261 if (currentSignal & SIGNAL_ISP_START_BAYER_DEQUEUE)
2262 {
2263 struct camera2_shot_ext *shot_ext;
2264 int bayerIndexToDequeue = 0;
2265 int processingFrameCnt = 0;
2266 ALOGV("DEBUG(%s): IspThread processing SIGNAL_ISP_START_BAYER_DEQUEUE", __FUNCTION__);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002267 bayerIndexToDequeue = m_BayerManager->GetIndexForIspDequeue(&processingFrameCnt);
2268 m_ispProcessingFrameCnt = processingFrameCnt;
2269 m_previewOutput = 0;
2270 m_recordOutput = 0;
2271 shot_ext = (struct camera2_shot_ext *)(m_camera_info.sensor.buffer[bayerIndexToDequeue].virt.extP[1]);
2272 if (processingFrameCnt != -1 || m_scp_flushing) // bubble
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002273 {
2274 if (shot_ext->request_scc) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002275 m_streamThreads[1]->SetSignal(SIGNAL_STREAM_DATA_COMING);
2276 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002277 m_previewOutput = shot_ext->shot.ctl.request.outputStreams[0];
2278 m_recordOutput = shot_ext->shot.ctl.request.outputStreams[2];
2279 if (m_previewOutput || m_recordOutput) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002280 m_streamThreads[0]->SetSignal(SIGNAL_STREAM_DATA_COMING);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002281 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002282 }
Alex Ray3f0357b2012-07-30 16:42:12 -07002283 ALOGV("### isp DQBUF start");
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002284 index = cam_int_dqbuf(&(m_camera_info.isp));
Alex Ray3f0357b2012-07-30 16:42:12 -07002285 ALOGV("### isp DQBUF done bayerIndex(%d) for frameCnt(%d)", index, processingFrameCnt);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002286 shot_ext = (struct camera2_shot_ext *)(m_camera_info.sensor.buffer[index].virt.extP[1]);
2287 ALOGV("(%s): SCP_CLOSING check sensor(%d) scc(%d) scp(%d) ", __FUNCTION__,
2288 shot_ext->request_sensor, shot_ext->request_scc, shot_ext->request_scp);
2289 if (shot_ext->request_scc + shot_ext->request_scp + shot_ext->request_sensor == 0) {
2290 ALOGV("(%s): SCP_CLOSING check OK ", __FUNCTION__);
2291 m_scp_closed = true;
2292 }
2293 else
2294 m_scp_closed = false;
2295 if (processingFrameCnt != -1) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002296 DumpInfoWithShot(shot_ext);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002297 m_requestManager->ApplyDynamicMetadata(shot_ext, processingFrameCnt);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002298 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002299 m_BayerManager->MarkIspDequeue(index);
2300 if (m_BayerManager->GetNumOnIsp() != 0) {
2301 selfThread->SetSignal(SIGNAL_ISP_START_BAYER_DEQUEUE);
2302 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002303 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002304
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002305 return;
2306}
2307
2308void ExynosCameraHWInterface2::m_streamThreadInitialize(SignalDrivenThread * self)
2309{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002310 StreamThread * selfThread = ((StreamThread*)self);
2311 ALOGV("DEBUG(%s): ", __FUNCTION__ );
2312 memset(&(selfThread->m_parameters), 0, sizeof(stream_parameters_t));
2313 selfThread->m_isBufferInit = false;
2314
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002315 return;
2316}
2317
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002318void ExynosCameraHWInterface2::m_streamThreadFunc(SignalDrivenThread * self)
2319{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002320 uint32_t currentSignal = self->GetProcessingSignal();
2321 StreamThread * selfThread = ((StreamThread*)self);
2322 stream_parameters_t *selfStreamParms = &(selfThread->m_parameters);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002323 record_parameters_t *selfRecordParms = &(selfThread->m_recordParameters);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002324 node_info_t *currentNode = &(selfStreamParms->node);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002325
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002326 ALOGV("DEBUG(%s): m_streamThreadFunc[%d] (%x)", __FUNCTION__, selfThread->m_index, currentSignal);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002327
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002328 if (currentSignal & SIGNAL_STREAM_CHANGE_PARAMETER) {
2329 ALOGV("DEBUG(%s): processing SIGNAL_STREAM_CHANGE_PARAMETER", __FUNCTION__);
2330 selfThread->applyChange();
2331 if (selfStreamParms->streamType==1) {
2332 m_resizeBuf.size.extS[0] = ALIGN(selfStreamParms->outputWidth, 16) * ALIGN(selfStreamParms->outputHeight, 16) * 2;
2333 m_resizeBuf.size.extS[1] = 0;
2334 m_resizeBuf.size.extS[2] = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002335
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002336 if (allocCameraMemory(selfStreamParms->ionClient, &m_resizeBuf, 1) == -1) {
2337 ALOGE("ERR(%s): Failed to allocate resize buf", __FUNCTION__);
2338 }
2339 }
2340 ALOGV("DEBUG(%s): processing SIGNAL_STREAM_CHANGE_PARAMETER DONE", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002341 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002342
2343 if (currentSignal & SIGNAL_THREAD_RELEASE) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002344 int i, index = -1, cnt_to_dq = 0;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002345 status_t res;
2346 ALOGV("DEBUG(%s): processing SIGNAL_THREAD_RELEASE", __FUNCTION__);
2347
2348
2349
2350 if (selfThread->m_isBufferInit) {
2351 for ( i=0 ; i < selfStreamParms->numSvcBuffers; i++) {
2352 ALOGV("DEBUG(%s): checking buffer index[%d] - status(%d)",
2353 __FUNCTION__, i, selfStreamParms->svcBufStatus[i]);
2354 if (selfStreamParms->svcBufStatus[i] ==ON_DRIVER) cnt_to_dq++;
2355 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002356
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002357 m_scp_closing = true;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002358 ALOGV("DEBUG(%s): calling stream(%d) streamoff (fd:%d)", __FUNCTION__,
2359 selfThread->m_index, selfStreamParms->fd);
2360 cam_int_streamoff(&(selfStreamParms->node));
2361 ALOGV("DEBUG(%s): calling stream(%d) streamoff done", __FUNCTION__, selfThread->m_index);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002362 if (selfStreamParms->streamType == 0) {
2363 ALOGV("DEBUG(%s): calling stream(%d) reqbuf 0 (fd:%d)", __FUNCTION__,
2364 selfThread->m_index, selfStreamParms->fd);
2365 currentNode->buffers = 0;
2366 cam_int_reqbufs(currentNode);
2367 ALOGV("DEBUG(%s): calling stream(%d) reqbuf 0 DONE(fd:%d)", __FUNCTION__,
2368 selfThread->m_index, selfStreamParms->fd);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002369 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002370 selfThread->m_releasing = false;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002371 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002372 if (selfThread->m_index == 1 && m_resizeBuf.size.s != 0) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002373 freeCameraMemory(&m_resizeBuf, 1);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002374 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002375 if (selfThread->m_index == 2 && m_resizeBuf2.size.s != 0) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002376 freeCameraMemory(&m_resizeBuf2, 1);
2377 }
2378 selfThread->m_isBufferInit = false;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002379 selfThread->m_index = 255;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002380
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002381 ALOGV("DEBUG(%s): processing SIGNAL_THREAD_RELEASE DONE", __FUNCTION__);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002382
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002383 return;
2384 }
2385
2386 if (currentSignal & SIGNAL_STREAM_DATA_COMING) {
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002387 buffer_handle_t * buf = NULL;
2388 status_t res;
2389 void *virtAddr[3];
2390 int i, j;
2391 int index;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002392 ALOGV("DEBUG(%s): stream(%d) processing SIGNAL_STREAM_DATA_COMING",
2393 __FUNCTION__,selfThread->m_index);
2394 if (!(selfThread->m_isBufferInit)) {
2395 for ( i=0 ; i < selfStreamParms->numSvcBuffers; i++) {
2396 res = selfStreamParms->streamOps->dequeue_buffer(selfStreamParms->streamOps, &buf);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002397 if (res != NO_ERROR || buf == NULL) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002398 ALOGE("ERR(%s): Init: unable to dequeue buffer : %d",__FUNCTION__ , res);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002399 return;
2400 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002401 ALOGV("DEBUG(%s): got buf(%x) version(%d), numFds(%d), numInts(%d)", __FUNCTION__, (uint32_t)(*buf),
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002402 ((native_handle_t*)(*buf))->version, ((native_handle_t*)(*buf))->numFds, ((native_handle_t*)(*buf))->numInts);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002403
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002404 if (m_grallocHal->lock(m_grallocHal, *buf,
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002405 selfStreamParms->usage,
2406 0, 0, selfStreamParms->outputWidth, selfStreamParms->outputHeight, virtAddr) != 0) {
2407 ALOGE("ERR(%s): could not obtain gralloc buffer", __FUNCTION__);
2408 return;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002409 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002410 ALOGV("DEBUG(%s): locked img buf plane0(%x) plane1(%x) plane2(%x)",
2411 __FUNCTION__, (unsigned int)virtAddr[0], (unsigned int)virtAddr[1], (unsigned int)virtAddr[2]);
2412
2413 index = selfThread->findBufferIndex(virtAddr[0]);
2414 if (index == -1) {
2415 ALOGE("ERR(%s): could not find buffer index", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002416 }
2417 else {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002418 ALOGV("DEBUG(%s): found buffer index[%d] - status(%d)",
2419 __FUNCTION__, index, selfStreamParms->svcBufStatus[index]);
2420 if (selfStreamParms->svcBufStatus[index]== REQUIRES_DQ_FROM_SVC)
2421 selfStreamParms->svcBufStatus[index] = ON_DRIVER;
2422 else if (selfStreamParms->svcBufStatus[index]== ON_SERVICE)
2423 selfStreamParms->svcBufStatus[index] = ON_HAL;
2424 else {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002425 ALOGV("DBG(%s): buffer status abnormal (%d) "
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002426 , __FUNCTION__, selfStreamParms->svcBufStatus[index]);
2427 }
2428 if (*buf != selfStreamParms->svcBufHandle[index])
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002429 ALOGV("DBG(%s): different buf_handle index ", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002430 else
2431 ALOGV("DEBUG(%s): same buf_handle index", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002432 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002433 m_svcBufIndex = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002434 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002435 selfThread->m_isBufferInit = true;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002436 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002437
2438 if (m_recordingEnabled && m_needsRecordBufferInit) {
2439 ALOGV("DEBUG(%s): Recording Buffer Initialization numsvcbuf(%d)",
2440 __FUNCTION__, selfRecordParms->numSvcBuffers);
2441
2442 m_resizeBuf2.size.extS[0] = ALIGN(selfRecordParms->outputWidth, 32) * ALIGN(selfRecordParms->outputHeight, 32) * 4;
2443 m_resizeBuf2.size.extS[1] = 0;
2444 m_resizeBuf2.size.extS[2] = 0;
2445 ALOGV("DEBUG(%s): resizebuf2 size0(%d) size1(%d)", __FUNCTION__, m_resizeBuf2.size.extS[0], m_resizeBuf2.size.extS[1]);
2446 if (allocCameraMemory(selfStreamParms->ionClient, &m_resizeBuf2, 1) == -1) {
2447 ALOGE("ERR(%s): Failed to allocate resize buf2", __FUNCTION__);
2448 }
2449
2450 int checkingIndex = 0;
2451 bool found = false;
2452 for ( i=0 ; i < selfRecordParms->numSvcBuffers; i++) {
2453 res = selfRecordParms->streamOps->dequeue_buffer(selfRecordParms->streamOps, &buf);
2454 if (res != NO_ERROR || buf == NULL) {
2455 ALOGE("ERR(%s): Init: unable to dequeue buffer : %d",__FUNCTION__ , res);
2456 return;
2457 }
2458 selfRecordParms->numBufsInHal++;
2459 ALOGV("DEBUG(%s): [record] got buf(%x) bufInHal(%d) version(%d), numFds(%d), numInts(%d)", __FUNCTION__, (uint32_t)(*buf),
2460 selfRecordParms->numBufsInHal, ((native_handle_t*)(*buf))->version, ((native_handle_t*)(*buf))->numFds, ((native_handle_t*)(*buf))->numInts);
2461
2462 if (m_grallocHal->lock(m_grallocHal, *buf,
2463 selfRecordParms->usage, 0, 0,
2464 selfRecordParms->outputWidth, selfRecordParms->outputHeight, virtAddr) != 0) {
2465 ALOGE("ERR(%s): could not obtain gralloc buffer", __FUNCTION__);
2466 }
2467 else {
2468 ALOGV("DEBUG(%s): [record] locked img buf plane0(%x) plane1(%x) plane2(%x)",
2469 __FUNCTION__, (unsigned int)virtAddr[0], (unsigned int)virtAddr[1], (unsigned int)virtAddr[2]);
2470
2471 }
2472 found = false;
2473 for (checkingIndex = 0; checkingIndex < selfRecordParms->numSvcBuffers ; checkingIndex++) {
2474 //ALOGV("DEBUG(%s) : comparing %d %x %x", __FUNCTION__, checkingIndex,
2475 //selfRecordParms->svcBufHandle[checkingIndex], *buf);
2476 if (selfRecordParms->svcBufHandle[checkingIndex] == *buf ) {
2477 found = true;
2478 break;
2479 }
2480 }
2481 ALOGV("DEBUG(%s): [record] found(%d) - index[%d]", __FUNCTION__, found, checkingIndex);
2482 if (!found) break;
2483 index = checkingIndex;
2484
2485
2486 if (index == -1) {
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002487 ALOGD("ERR(%s): could not find buffer index", __FUNCTION__);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002488 }
2489 else {
2490 ALOGV("DEBUG(%s): found buffer index[%d] - status(%d)",
2491 __FUNCTION__, index, selfRecordParms->svcBufStatus[index]);
2492 if (selfRecordParms->svcBufStatus[index]== ON_SERVICE)
2493 selfRecordParms->svcBufStatus[index] = ON_HAL;
2494 else {
2495 ALOGV("DBG(%s): buffer status abnormal (%d) "
2496 , __FUNCTION__, selfRecordParms->svcBufStatus[index]);
2497 }
2498 if (*buf != selfRecordParms->svcBufHandle[index])
2499 ALOGV("DBG(%s): different buf_handle index ", __FUNCTION__);
2500 else
2501 ALOGV("DEBUG(%s): same buf_handle index", __FUNCTION__);
2502 }
2503 selfRecordParms->m_svcBufIndex = 0;
2504 }
2505 m_needsRecordBufferInit = false;
2506 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002507
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002508 do {
2509 if (selfStreamParms->streamType == 0) {
2510 ALOGV("DEBUG(%s): stream(%d) type(%d) DQBUF START ",__FUNCTION__,
2511 selfThread->m_index, selfStreamParms->streamType);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002512
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002513 index = cam_int_dqbuf(&(selfStreamParms->node));
2514 ALOGV("DEBUG(%s): stream(%d) type(%d) DQBUF done index(%d)",__FUNCTION__,
2515 selfThread->m_index, selfStreamParms->streamType, index);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002516
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002517
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002518 if (selfStreamParms->svcBufStatus[index] != ON_DRIVER)
2519 ALOGD("DBG(%s): DQed buffer status abnormal (%d) ",
2520 __FUNCTION__, selfStreamParms->svcBufStatus[index]);
2521 selfStreamParms->svcBufStatus[index] = ON_HAL;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002522
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002523 if (m_recordOutput && m_recordingEnabled) {
2524 ALOGV("DEBUG(%s): Entering record frame creator, index(%d)",__FUNCTION__, selfRecordParms->m_svcBufIndex);
2525 bool found = false;
2526 for (int i = 0 ; selfRecordParms->numSvcBuffers ; i++) {
2527 if (selfRecordParms->svcBufStatus[selfRecordParms->m_svcBufIndex] == ON_HAL) {
2528 found = true;
2529 break;
2530 }
2531 selfRecordParms->m_svcBufIndex++;
2532 if (selfRecordParms->m_svcBufIndex >= selfRecordParms->numSvcBuffers)
2533 selfRecordParms->m_svcBufIndex = 0;
2534 }
2535 if (!found) {
2536 ALOGE("(%s): cannot find free recording buffer", __FUNCTION__);
2537 selfRecordParms->m_svcBufIndex++;
2538 break;
2539 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002540
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002541 if (m_exynosVideoCSC) {
2542 int videoW = selfRecordParms->outputWidth, videoH = selfRecordParms->outputHeight;
2543 int cropX, cropY, cropW, cropH = 0;
2544 int previewW = selfStreamParms->outputWidth, previewH = selfStreamParms->outputHeight;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002545
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002546 m_getRatioSize(previewW, previewH,
2547 videoW, videoH,
2548 &cropX, &cropY,
2549 &cropW, &cropH,
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002550 0);
2551
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002552 ALOGV("DEBUG(%s):cropX = %d, cropY = %d, cropW = %d, cropH = %d",
2553 __FUNCTION__, cropX, cropY, cropW, cropH);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002554
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002555
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002556 csc_set_src_format(m_exynosVideoCSC,
2557 //ALIGN(previewW, 32), ALIGN(previewH, 32),
2558 previewW, previewH,
2559 cropX, cropY, cropW, cropH,
2560 HAL_PIXEL_FORMAT_YV12,
2561 0);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002562
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002563 csc_set_dst_format(m_exynosVideoCSC,
2564 ALIGN(videoW, 32), ALIGN(videoH, 32),
2565 0, 0, videoW, videoH,
2566 HAL_PIXEL_FORMAT_RGBA_8888,
2567 1);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002568
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002569 ALOGV("DEBUG(%s) [1]-- bufindex(%d)", __FUNCTION__, selfRecordParms->m_svcBufIndex);
2570
2571 csc_set_src_buffer(m_exynosVideoCSC,
2572 (void **)(&(selfStreamParms->svcBuffers[index].fd.fd)));
2573 for (int i=0 ; i <3 ; i++)
2574 ALOGV("DEBUG(%s): src [%d] - %d, %x size(%d)",
2575 __FUNCTION__, i, selfStreamParms->svcBuffers[index].fd.extFd[i],
2576 selfStreamParms->svcBuffers[index].virt.extP[i],
2577 selfStreamParms->svcBuffers[index].size.extS[i]);
2578 //m_resizeBuf2.fd.extFd[2] = 0;
2579 for (int i=0 ; i <selfRecordParms->svcPlanes; i++)
2580 ALOGV("DEBUG(%s): m_resizeBuf2.fd.extFd[%d]=%d addr(%x) m_resizeBuf2.size.extS[%d]=%d",
2581 __FUNCTION__, i, m_resizeBuf2.fd.extFd[i], (unsigned int)m_resizeBuf2.virt.extP[i], i,
2582 m_resizeBuf2.size.extS[i]);
2583 csc_set_dst_buffer(m_exynosVideoCSC,
2584 (void **)(&(m_resizeBuf2.fd.fd)));
2585
2586 if (csc_convert(m_exynosVideoCSC) != 0) {
2587 ALOGE("ERR(%s):csc_convert() fail", __FUNCTION__);
2588 }
2589 else {
2590 ALOGV("ERR(%s):csc_convert() SUCCESS", __FUNCTION__);
2591 }
2592 /*tempFd = selfStreamParms->svcBuffers[index].fd.extFd[2];
2593 selfStreamParms->svcBuffers[index].fd.extFd[2] = selfStreamParms->svcBuffers[index].fd.extFd[1];
2594 selfStreamParms->svcBuffers[index].fd.extFd[1] = tempFd; */
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002595
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002596 ALOGV("DEBUG(%s): svc addr[0] %x addr[1] %x", __FUNCTION__,
2597 (unsigned int)selfRecordParms->svcBuffers[selfRecordParms->m_svcBufIndex].virt.extP[0],
2598 (unsigned int)selfRecordParms->svcBuffers[selfRecordParms->m_svcBufIndex].virt.extP[1]);
2599 memcpy(selfRecordParms->svcBuffers[selfRecordParms->m_svcBufIndex].virt.extP[0],
2600 m_resizeBuf2.virt.extP[0], videoW * videoH * 4);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002601 }
2602 else {
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002603 ALOGE("ERR(%s):m_exynosVideoCSC == NULL", __FUNCTION__);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002604 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002605
2606 /* res = selfRecordParms->streamOps->enqueue_buffer(selfRecordParms->streamOps,
2607 m_requestManager->GetTimestamp(m_ispProcessingFrameCnt),
2608 &(selfRecordParms->svcBufHandle[selfRecordParms->m_svcBufIndex]));*/
2609 res = selfRecordParms->streamOps->enqueue_buffer(selfRecordParms->streamOps,
2610 systemTime(),
2611 &(selfRecordParms->svcBufHandle[selfRecordParms->m_svcBufIndex]));
2612 ALOGV("DEBUG(%s): stream(%d) record enqueue_buffer to svc done res(%d)", __FUNCTION__,
2613 selfThread->m_index, res);
2614 if (res == 0) {
2615 selfRecordParms->svcBufStatus[selfRecordParms->m_svcBufIndex] = ON_SERVICE;
2616 selfRecordParms->numBufsInHal--;
2617 }
2618 /*selfRecordParms->m_svcBufIndex++;
2619 if (selfRecordParms->m_svcBufIndex >= selfRecordParms->numSvcBuffers)
2620 selfRecordParms->m_svcBufIndex = 0;*/
2621 m_requestManager->NotifyStreamOutput(m_ispProcessingFrameCnt, 2);
2622
2623 }
2624 if (m_previewOutput) {
2625 res = selfStreamParms->streamOps->enqueue_buffer(selfStreamParms->streamOps,
2626 m_requestManager->GetTimestamp(m_ispProcessingFrameCnt), &(selfStreamParms->svcBufHandle[index]));
2627 ALOGV("DEBUG(%s): stream(%d) enqueue_buffer to svc done res(%d)", __FUNCTION__, selfThread->m_index, res);
2628 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002629 else {
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002630 res = selfStreamParms->streamOps->cancel_buffer(selfStreamParms->streamOps,
2631 &(selfStreamParms->svcBufHandle[index]));
2632 ALOGV("DEBUG(%s): stream(%d) cancel_buffer to svc done res(%d)", __FUNCTION__, selfThread->m_index, res);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002633 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002634 if (res == 0) {
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002635 selfStreamParms->svcBufStatus[index] = ON_SERVICE;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002636 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002637 else {
2638 selfStreamParms->svcBufStatus[index] = ON_HAL;
2639 }
2640 m_requestManager->NotifyStreamOutput(m_ispProcessingFrameCnt, selfThread->m_index);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002641 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002642 else if (selfStreamParms->streamType == 1) {
2643 ALOGV("DEBUG(%s): stream(%d) type(%d) DQBUF START ",__FUNCTION__,
2644 selfThread->m_index, selfStreamParms->streamType);
2645 index = cam_int_dqbuf(&(selfStreamParms->node));
2646 ALOGV("DEBUG(%s): stream(%d) type(%d) DQBUF done index(%d)",__FUNCTION__,
2647 selfThread->m_index, selfStreamParms->streamType, index);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002648
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002649 m_jpegEncodingFrameCnt = m_ispProcessingFrameCnt;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002650
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002651 bool ret = false;
2652 int pictureW, pictureH, pictureFramesize = 0;
2653 int pictureFormat;
2654 int cropX, cropY, cropW, cropH = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002655
2656
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002657 ExynosBuffer jpegBuf, resizeBufInfo;
Rebecca Schultz Zavina8b0b072012-06-26 12:50:15 -07002658
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002659 ExynosRect m_orgPictureRect;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002660
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002661 m_orgPictureRect.w = selfStreamParms->outputWidth;
2662 m_orgPictureRect.h = selfStreamParms->outputHeight;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002663
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002664 ExynosBuffer* m_pictureBuf = &(m_camera_info.capture.buffer[index]);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002665
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002666 pictureW = getSccOutputSizeX(m_cameraId);
2667 pictureH = getSccOutputSizeY(m_cameraId);
2668 pictureFormat = V4L2_PIX_FMT_YUYV;
2669 pictureFramesize = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(pictureFormat), pictureW, pictureH);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002670
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002671 if (m_exynosPictureCSC) {
2672 m_getRatioSize(pictureW, pictureH,
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002673 m_orgPictureRect.w, m_orgPictureRect.h,
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002674 &cropX, &cropY,
2675 &cropW, &cropH,
2676 0);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002677
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002678 ALOGV("DEBUG(%s):cropX = %d, cropY = %d, cropW = %d, cropH = %d",
2679 __FUNCTION__, cropX, cropY, cropW, cropH);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002680
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002681 csc_set_src_format(m_exynosPictureCSC,
2682 ALIGN(pictureW, 16), ALIGN(pictureH, 16),
2683 cropX, cropY, cropW, cropH,
2684 V4L2_PIX_2_HAL_PIXEL_FORMAT(pictureFormat),
2685 0);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002686
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002687 csc_set_dst_format(m_exynosPictureCSC,
2688 m_orgPictureRect.w, m_orgPictureRect.h,
2689 0, 0, m_orgPictureRect.w, m_orgPictureRect.h,
2690 V4L2_PIX_2_HAL_PIXEL_FORMAT(V4L2_PIX_FMT_NV16),
2691 0);
2692 csc_set_src_buffer(m_exynosPictureCSC,
2693 (void **)&m_pictureBuf->fd.fd);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002694
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002695 csc_set_dst_buffer(m_exynosPictureCSC,
2696 (void **)&m_resizeBuf.fd.fd);
2697 for (int i=0 ; i < 3 ; i++)
2698 ALOGV("DEBUG(%s): m_resizeBuf.virt.extP[%d]=%d m_resizeBuf.size.extS[%d]=%d",
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002699 __FUNCTION__, i, m_resizeBuf.fd.extFd[i], i, m_resizeBuf.size.extS[i]);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002700
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002701 if (csc_convert(m_exynosPictureCSC) != 0)
2702 ALOGE("ERR(%s): csc_convert() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002703
2704
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002705 }
2706 else {
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002707 ALOGE("ERR(%s): m_exynosPictureCSC == NULL", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002708 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002709
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002710 resizeBufInfo = m_resizeBuf;
2711
2712 m_getAlignedYUVSize(V4L2_PIX_FMT_NV16, m_orgPictureRect.w, m_orgPictureRect.h, &m_resizeBuf);
2713
2714 for (int i = 1; i < 3; i++) {
2715 if (m_resizeBuf.size.extS[i] != 0)
2716 m_resizeBuf.fd.extFd[i] = m_resizeBuf.fd.extFd[i-1] + m_resizeBuf.size.extS[i-1];
2717
2718 ALOGV("(%s): m_resizeBuf.size.extS[%d] = %d", __FUNCTION__, i, m_resizeBuf.size.extS[i]);
2719 }
2720
2721
2722 ExynosRect jpegRect;
2723 bool found = false;
2724 jpegRect.w = m_orgPictureRect.w;
2725 jpegRect.h = m_orgPictureRect.h;
2726 jpegRect.colorFormat = V4L2_PIX_FMT_NV16;
2727
2728 jpegBuf.size.extS[0] = 5*1024*1024;
2729 jpegBuf.size.extS[1] = 0;
2730 jpegBuf.size.extS[2] = 0;
2731
2732 allocCameraMemory(currentNode->ionClient, &jpegBuf, 1);
2733
2734 ALOGV("DEBUG(%s): jpegBuf.size.s = %d , jpegBuf.virt.p = %x", __FUNCTION__,
2735 jpegBuf.size.s, (unsigned int)jpegBuf.virt.p);
2736
2737
2738 if (yuv2Jpeg(&m_resizeBuf, &jpegBuf, &jpegRect) == false)
2739 ALOGE("ERR(%s):yuv2Jpeg() fail", __FUNCTION__);
2740 cam_int_qbuf(&(selfStreamParms->node), index);
2741 ALOGV("DEBUG(%s): stream(%d) type(%d) QBUF DONE ",__FUNCTION__,
2742 selfThread->m_index, selfStreamParms->streamType);
2743
2744 m_resizeBuf = resizeBufInfo;
2745
2746 for (int i = 0; i < selfStreamParms->numSvcBuffers ; i++) {
2747 if (selfStreamParms->svcBufStatus[m_svcBufIndex] == ON_HAL) {
2748 found = true;
2749 break;
2750 }
2751 m_svcBufIndex++;
2752 if (m_svcBufIndex >= selfStreamParms->numSvcBuffers) m_svcBufIndex = 0;
2753 }
2754 if (!found) {
2755 ALOGE("ERR(%s): NO free SVC buffer for JPEG", __FUNCTION__);
2756 }
2757 else {
2758 memcpy(selfStreamParms->svcBuffers[m_svcBufIndex].virt.extP[0], jpegBuf.virt.extP[0], 5*1024*1024);
2759
2760 res = selfStreamParms->streamOps->enqueue_buffer(selfStreamParms->streamOps,
2761 m_requestManager->GetTimestamp(m_jpegEncodingFrameCnt), &(selfStreamParms->svcBufHandle[m_svcBufIndex]));
2762
2763 freeCameraMemory(&jpegBuf, 1);
2764 ALOGV("DEBUG(%s): stream(%d) enqueue_buffer index(%d) to svc done res(%d)",
2765 __FUNCTION__, selfThread->m_index, m_svcBufIndex, res);
2766 if (res == 0) {
2767 selfStreamParms->svcBufStatus[m_svcBufIndex] = ON_SERVICE;
2768 }
2769 else {
2770 selfStreamParms->svcBufStatus[m_svcBufIndex] = ON_HAL;
2771 }
2772 m_requestManager->NotifyStreamOutput(m_jpegEncodingFrameCnt, selfThread->m_index);
2773 }
2774
2775 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002776 }
Sungjoong Kangb5237e62012-07-27 07:39:05 -07002777 while (0);
2778
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002779 if (selfStreamParms->streamType==0 && m_recordOutput && m_recordingEnabled) {
2780 do {
2781 ALOGV("DEBUG(%s): record currentBuf#(%d)", __FUNCTION__ , selfRecordParms->numBufsInHal);
2782 if (selfRecordParms->numBufsInHal>=1)
2783 {
2784 ALOGV("DEBUG(%s): breaking", __FUNCTION__);
2785 break;
2786 }
2787 res = selfRecordParms->streamOps->dequeue_buffer(selfRecordParms->streamOps, &buf);
2788 if (res != NO_ERROR || buf == NULL) {
2789 ALOGV("DEBUG(%s): record stream(%d) dequeue_buffer fail res(%d)",__FUNCTION__ , selfThread->m_index, res);
2790 break;
2791 }
2792 selfRecordParms->numBufsInHal ++;
2793 ALOGV("DEBUG(%s): record got buf(%x) numBufInHal(%d) version(%d), numFds(%d), numInts(%d)", __FUNCTION__, (uint32_t)(*buf),
2794 selfRecordParms->numBufsInHal, ((native_handle_t*)(*buf))->version, ((native_handle_t*)(*buf))->numFds, ((native_handle_t*)(*buf))->numInts);
2795 const private_handle_t *priv_handle = reinterpret_cast<const private_handle_t *>(*buf);
2796
2797 bool found = false;
2798 int checkingIndex = 0;
2799 for (checkingIndex = 0; checkingIndex < selfRecordParms->numSvcBuffers ; checkingIndex++) {
2800 if (priv_handle->fd == selfRecordParms->svcBuffers[checkingIndex].fd.extFd[0] ) {
2801 found = true;
2802 break;
2803 }
2804 }
2805 ALOGV("DEBUG(%s): recording dequeueed_buffer found index(%d)", __FUNCTION__, found);
2806 if (!found) break;
2807 index = checkingIndex;
2808 if (selfRecordParms->svcBufStatus[index] == ON_SERVICE) {
2809 selfRecordParms->svcBufStatus[index] = ON_HAL;
2810 }
2811 else {
2812 ALOGV("DEBUG(%s): record bufstatus abnormal [%d] status = %d", __FUNCTION__,
2813 index, selfRecordParms->svcBufStatus[index]);
2814 }
2815 } while (0);
2816 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002817 while(1) {
2818 res = selfStreamParms->streamOps->dequeue_buffer(selfStreamParms->streamOps, &buf);
2819 if (res != NO_ERROR || buf == NULL) {
2820 ALOGV("DEBUG(%s): stream(%d) dequeue_buffer fail res(%d)",__FUNCTION__ , selfThread->m_index, res);
2821 break;
2822 }
2823
2824 ALOGV("DEBUG(%s): got buf(%x) version(%d), numFds(%d), numInts(%d)", __FUNCTION__, (uint32_t)(*buf),
2825 ((native_handle_t*)(*buf))->version, ((native_handle_t*)(*buf))->numFds, ((native_handle_t*)(*buf))->numInts);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002826 const private_handle_t *priv_handle = reinterpret_cast<const private_handle_t *>(*buf);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002827
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002828 bool found = false;
2829 int checkingIndex = 0;
2830 for (checkingIndex = 0; checkingIndex < selfStreamParms->numSvcBuffers ; checkingIndex++) {
2831 if (priv_handle->fd == selfStreamParms->svcBuffers[checkingIndex].fd.extFd[0] ) {
2832 found = true;
2833 break;
2834 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002835 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002836 ALOGV("DEBUG(%s): post_dequeue_buffer found(%d)", __FUNCTION__, found);
2837 if (!found) break;
2838 ALOGV("DEBUG(%s): preparing to qbuf [%d]", __FUNCTION__, checkingIndex);
2839 index = checkingIndex;
2840 if (index < selfStreamParms->numHwBuffers) {
2841 uint32_t plane_index = 0;
2842 ExynosBuffer* currentBuf = &(selfStreamParms->svcBuffers[index]);
2843 struct v4l2_buffer v4l2_buf;
2844 struct v4l2_plane planes[VIDEO_MAX_PLANES];
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002845
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002846 v4l2_buf.m.planes = planes;
2847 v4l2_buf.type = currentNode->type;
2848 v4l2_buf.memory = currentNode->memory;
2849 v4l2_buf.index = index;
2850 v4l2_buf.length = currentNode->planes;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002851
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002852 v4l2_buf.m.planes[0].m.fd = priv_handle->fd;
Alex Ray6bbb5932012-07-27 17:19:48 -07002853 v4l2_buf.m.planes[2].m.fd = priv_handle->fd1;
2854 v4l2_buf.m.planes[1].m.fd = priv_handle->fd2;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002855 for (plane_index=0 ; plane_index < v4l2_buf.length ; plane_index++) {
2856 v4l2_buf.m.planes[plane_index].length = currentBuf->size.extS[plane_index];
2857 ALOGV("DEBUG(%s): plane(%d): fd(%d) length(%d)",
2858 __FUNCTION__, plane_index, v4l2_buf.m.planes[plane_index].m.fd,
2859 v4l2_buf.m.planes[plane_index].length);
2860 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002861
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002862 if (selfStreamParms->streamType == 0) {
2863 if (exynos_v4l2_qbuf(currentNode->fd, &v4l2_buf) < 0) {
2864 ALOGE("ERR(%s): stream id(%d) exynos_v4l2_qbuf() fail",
2865 __FUNCTION__, selfThread->m_index);
2866 return;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002867 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002868 selfStreamParms->svcBufStatus[index] = ON_DRIVER;
2869 ALOGV("DEBUG(%s): stream id(%d) type0 QBUF done index(%d)",
2870 __FUNCTION__, selfThread->m_index, index);
2871 }
2872 else if (selfStreamParms->streamType == 1) {
2873 selfStreamParms->svcBufStatus[index] = ON_HAL;
2874 ALOGV("DEBUG(%s): stream id(%d) type1 DQBUF done index(%d)",
2875 __FUNCTION__, selfThread->m_index, index);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002876 }
2877 }
2878 }
2879 ALOGV("DEBUG(%s): stream(%d) processing SIGNAL_STREAM_DATA_COMING DONE",
2880 __FUNCTION__,selfThread->m_index);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002881 }
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002882 return;
2883}
2884
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002885bool ExynosCameraHWInterface2::yuv2Jpeg(ExynosBuffer *yuvBuf,
2886 ExynosBuffer *jpegBuf,
2887 ExynosRect *rect)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002888{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002889 unsigned char *addr;
2890
2891 ExynosJpegEncoderForCamera jpegEnc;
2892 bool ret = false;
2893 int res = 0;
2894
2895 unsigned int *yuvSize = yuvBuf->size.extS;
2896
2897 if (jpegEnc.create()) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002898 ALOGE("ERR(%s):jpegEnc.create() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002899 goto jpeg_encode_done;
2900 }
2901
2902 if (jpegEnc.setQuality(100)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002903 ALOGE("ERR(%s):jpegEnc.setQuality() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002904 goto jpeg_encode_done;
2905 }
2906
2907 if (jpegEnc.setSize(rect->w, rect->h)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002908 ALOGE("ERR(%s):jpegEnc.setSize() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002909 goto jpeg_encode_done;
2910 }
2911 ALOGV("%s : width = %d , height = %d\n", __FUNCTION__, rect->w, rect->h);
2912
2913 if (jpegEnc.setColorFormat(rect->colorFormat)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002914 ALOGE("ERR(%s):jpegEnc.setColorFormat() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002915 goto jpeg_encode_done;
2916 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002917 ALOGV("%s : color = %d\n", __FUNCTION__, &(rect->colorFormat));
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002918
2919 if (jpegEnc.setJpegFormat(V4L2_PIX_FMT_JPEG_422)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002920 ALOGE("ERR(%s):jpegEnc.setJpegFormat() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002921 goto jpeg_encode_done;
2922 }
2923#if 0
2924 if (m_curCameraInfo->thumbnailW != 0 && m_curCameraInfo->thumbnailH != 0) {
2925 int thumbW = 0, thumbH = 0;
2926 mExifInfo.enableThumb = true;
2927 if (rect->w < 320 || rect->h < 240) {
2928 thumbW = 160;
2929 thumbH = 120;
2930 } else {
2931 thumbW = m_curCameraInfo->thumbnailW;
2932 thumbH = m_curCameraInfo->thumbnailH;
2933 }
2934 if (jpegEnc.setThumbnailSize(thumbW, thumbH)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002935 LOGE("ERR(%s):jpegEnc.setThumbnailSize(%d, %d) fail", __FUNCTION__, thumbW, thumbH);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002936 goto jpeg_encode_done;
2937 }
2938
2939 if (0 < m_jpegThumbnailQuality && m_jpegThumbnailQuality <= 100) {
2940 if (jpegEnc.setThumbnailQuality(m_jpegThumbnailQuality)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002941 LOGE("ERR(%s):jpegEnc.setThumbnailQuality(%d) fail", __FUNCTION__, m_jpegThumbnailQuality);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002942 goto jpeg_encode_done;
2943 }
2944 }
2945
2946 m_setExifChangedAttribute(&mExifInfo, rect);
2947 } else
2948#endif
2949 {
2950 mExifInfo.enableThumb = false;
2951 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002952 ALOGV("DEBUG(%s):calling jpegEnc.setInBuf() yuvSize(%d)", __FUNCTION__, *yuvSize);
2953 /*for (int i=0 ; i < 3 ; i++)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002954 ALOGV("DEBUG(%s):calling jpegEnc.setInBuf() virt.extP[%d]=%x extS[%d]=%d",
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002955 __FUNCTION__, i, yuvBuf->fd.extFd[i], i, yuvBuf->size.extS[i]);*/
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002956 if (jpegEnc.setInBuf((int *)&(yuvBuf->fd.fd), (int *)yuvSize)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002957 ALOGE("ERR(%s):jpegEnc.setInBuf() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002958 goto jpeg_encode_done;
2959 }
2960
2961 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 +09002962 ALOGE("ERR(%s):jpegEnc.setOutBuf() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002963 goto jpeg_encode_done;
2964 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002965 /*for (int i=0 ; i < 3 ; i++)
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002966 ALOGV("DEBUG(%s): jpegBuf->virt.extP[%d]=%x jpegBuf->size.extS[%d]=%d",
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002967 __FUNCTION__, i, jpegBuf->fd.extFd[i], i, jpegBuf->size.extS[i]);*/
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002968 memset(jpegBuf->virt.p,0,jpegBuf->size.extS[0] + jpegBuf->size.extS[1] + jpegBuf->size.extS[2]);
2969
2970 if (jpegEnc.updateConfig()) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002971 ALOGE("ERR(%s):jpegEnc.updateConfig() fail", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002972 goto jpeg_encode_done;
2973 }
2974
2975 if (res = jpegEnc.encode((int *)&jpegBuf->size.s, NULL)) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002976 ALOGE("ERR(%s):jpegEnc.encode() fail ret(%d)", __FUNCTION__, res);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002977 goto jpeg_encode_done;
2978 }
2979
2980 ret = true;
2981
2982jpeg_encode_done:
2983
2984 if (jpegEnc.flagCreate() == true)
2985 jpegEnc.destroy();
2986
2987 return ret;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002988}
2989
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002990
2991ExynosCameraHWInterface2::MainThread::~MainThread()
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07002992{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002993 ALOGD("(%s):", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002994}
2995
2996void ExynosCameraHWInterface2::MainThread::release()
2997{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09002998 ALOGD("(%s):", __func__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09002999 SetSignal(SIGNAL_THREAD_RELEASE);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003000}
3001
3002ExynosCameraHWInterface2::SensorThread::~SensorThread()
3003{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003004 ALOGD("(%s):", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003005}
3006
3007void ExynosCameraHWInterface2::SensorThread::release()
3008{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003009 ALOGD("(%s):", __func__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003010 SetSignal(SIGNAL_THREAD_RELEASE);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003011}
3012
3013ExynosCameraHWInterface2::IspThread::~IspThread()
3014{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003015 ALOGD("(%s):", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003016}
3017
3018void ExynosCameraHWInterface2::IspThread::release()
3019{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003020 ALOGD("(%s):", __func__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003021 SetSignal(SIGNAL_THREAD_RELEASE);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003022}
3023
3024ExynosCameraHWInterface2::StreamThread::~StreamThread()
3025{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003026 ALOGD("(%s):", __FUNCTION__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003027}
3028
3029void ExynosCameraHWInterface2::StreamThread::setParameter(stream_parameters_t * new_parameters)
3030{
3031 ALOGV("DEBUG(%s):", __FUNCTION__);
3032
3033 m_tempParameters = new_parameters;
3034
3035 SetSignal(SIGNAL_STREAM_CHANGE_PARAMETER);
3036
3037 // TODO : return synchronously (after setting parameters asynchronously)
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003038 usleep(2000);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003039}
3040
3041void ExynosCameraHWInterface2::StreamThread::applyChange()
3042{
3043 memcpy(&m_parameters, m_tempParameters, sizeof(stream_parameters_t));
3044
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003045 ALOGV("DEBUG(%s): Applying Stream paremeters width(%d), height(%d)",
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003046 __FUNCTION__, m_parameters.outputWidth, m_parameters.outputHeight);
3047}
3048
3049void ExynosCameraHWInterface2::StreamThread::release()
3050{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003051 ALOGV("(%s):", __func__);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003052 SetSignal(SIGNAL_THREAD_RELEASE);
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003053}
3054
3055int ExynosCameraHWInterface2::StreamThread::findBufferIndex(void * bufAddr)
3056{
3057 int index;
3058 for (index = 0 ; index < m_parameters.numSvcBuffers ; index++) {
3059 if (m_parameters.svcBuffers[index].virt.extP[0] == bufAddr)
3060 return index;
3061 }
3062 return -1;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003063}
3064
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003065void ExynosCameraHWInterface2::StreamThread::setRecordingParameter(record_parameters_t * recordParm)
3066{
3067 memcpy(&m_recordParameters, recordParm, sizeof(record_parameters_t));
3068}
3069
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003070int ExynosCameraHWInterface2::createIonClient(ion_client ionClient)
3071{
3072 if (ionClient == 0) {
3073 ionClient = ion_client_create();
3074 if (ionClient < 0) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003075 ALOGE("[%s]src ion client create failed, value = %d\n", __FUNCTION__, ionClient);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003076 return 0;
3077 }
3078 }
3079
3080 return ionClient;
3081}
3082
3083int ExynosCameraHWInterface2::deleteIonClient(ion_client ionClient)
3084{
3085 if (ionClient != 0) {
3086 if (ionClient > 0) {
3087 ion_client_destroy(ionClient);
3088 }
3089 ionClient = 0;
3090 }
3091
3092 return ionClient;
3093}
3094
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003095int ExynosCameraHWInterface2::allocCameraMemory(ion_client ionClient, ExynosBuffer *buf, int iMemoryNum)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003096{
3097 int ret = 0;
3098 int i = 0;
3099
3100 if (ionClient == 0) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003101 ALOGE("[%s] ionClient is zero (%d)\n", __FUNCTION__, ionClient);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003102 return -1;
3103 }
3104
3105 for (i=0;i<iMemoryNum;i++) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003106 if (buf->size.extS[i] == 0) {
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003107 break;
3108 }
3109
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003110 buf->fd.extFd[i] = ion_alloc(ionClient, \
3111 buf->size.extS[i], 0, ION_HEAP_EXYNOS_MASK,0);
3112 if ((buf->fd.extFd[i] == -1) ||(buf->fd.extFd[i] == 0)) {
3113 ALOGE("[%s]ion_alloc(%d) failed\n", __FUNCTION__, buf->size.extS[i]);
3114 buf->fd.extFd[i] = -1;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003115 freeCameraMemory(buf, iMemoryNum);
3116 return -1;
3117 }
3118
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003119 buf->virt.extP[i] = (char *)ion_map(buf->fd.extFd[i], \
3120 buf->size.extS[i], 0);
3121 if ((buf->virt.extP[i] == (char *)MAP_FAILED) || (buf->virt.extP[i] == NULL)) {
3122 ALOGE("[%s]src ion map failed(%d)\n", __FUNCTION__, buf->size.extS[i]);
3123 buf->virt.extP[i] = (char *)MAP_FAILED;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003124 freeCameraMemory(buf, iMemoryNum);
3125 return -1;
3126 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003127 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 -07003128 }
3129
3130 return ret;
3131}
3132
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003133void ExynosCameraHWInterface2::freeCameraMemory(ExynosBuffer *buf, int iMemoryNum)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003134{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003135
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003136 int i =0 ;
3137
3138 for (i=0;i<iMemoryNum;i++) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003139 if (buf->fd.extFd[i] != -1) {
3140 if (buf->virt.extP[i] != (char *)MAP_FAILED) {
3141 ion_unmap(buf->virt.extP[i], buf->size.extS[i]);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003142 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003143 ion_free(buf->fd.extFd[i]);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003144 }
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003145 buf->fd.extFd[i] = -1;
3146 buf->virt.extP[i] = (char *)MAP_FAILED;
3147 buf->size.extS[i] = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003148 }
3149}
3150
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003151void ExynosCameraHWInterface2::initCameraMemory(ExynosBuffer *buf, int iMemoryNum)
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003152{
3153 int i =0 ;
3154 for (i=0;i<iMemoryNum;i++) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003155 buf->virt.extP[i] = (char *)MAP_FAILED;
3156 buf->fd.extFd[i] = -1;
3157 buf->size.extS[i] = 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003158 }
3159}
3160
3161
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003162
3163
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003164static camera2_device_t *g_cam2_device = NULL;
Sungjoong Kangb5237e62012-07-27 07:39:05 -07003165static bool g_camera_vaild = false;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003166
3167static int HAL2_camera_device_close(struct hw_device_t* device)
3168{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003169 ALOGD("%s: ENTER", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003170 if (device) {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003171
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003172 camera2_device_t *cam_device = (camera2_device_t *)device;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003173 ALOGD("cam_device(0x%08x):", (unsigned int)cam_device);
3174 ALOGD("g_cam2_device(0x%08x):", (unsigned int)g_cam2_device);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003175 delete static_cast<ExynosCameraHWInterface2 *>(cam_device->priv);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003176 g_cam2_device = NULL;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003177 free(cam_device);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07003178 g_camera_vaild = false;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003179 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003180 ALOGD("%s: EXIT", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003181 return 0;
3182}
3183
3184static inline ExynosCameraHWInterface2 *obj(const struct camera2_device *dev)
3185{
3186 return reinterpret_cast<ExynosCameraHWInterface2 *>(dev->priv);
3187}
3188
3189static int HAL2_device_set_request_queue_src_ops(const struct camera2_device *dev,
3190 const camera2_request_queue_src_ops_t *request_src_ops)
3191{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003192 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003193 return obj(dev)->setRequestQueueSrcOps(request_src_ops);
3194}
3195
3196static int HAL2_device_notify_request_queue_not_empty(const struct camera2_device *dev)
3197{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003198 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003199 return obj(dev)->notifyRequestQueueNotEmpty();
3200}
3201
3202static int HAL2_device_set_frame_queue_dst_ops(const struct camera2_device *dev,
3203 const camera2_frame_queue_dst_ops_t *frame_dst_ops)
3204{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003205 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003206 return obj(dev)->setFrameQueueDstOps(frame_dst_ops);
3207}
3208
3209static int HAL2_device_get_in_progress_count(const struct camera2_device *dev)
3210{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003211 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003212 return obj(dev)->getInProgressCount();
3213}
3214
3215static int HAL2_device_flush_captures_in_progress(const struct camera2_device *dev)
3216{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003217 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003218 return obj(dev)->flushCapturesInProgress();
3219}
3220
3221static int HAL2_device_construct_default_request(const struct camera2_device *dev,
3222 int request_template, camera_metadata_t **request)
3223{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003224 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003225 return obj(dev)->constructDefaultRequest(request_template, request);
3226}
3227
3228static int HAL2_device_allocate_stream(
3229 const struct camera2_device *dev,
3230 // inputs
3231 uint32_t width,
3232 uint32_t height,
3233 int format,
3234 const camera2_stream_ops_t *stream_ops,
3235 // outputs
3236 uint32_t *stream_id,
3237 uint32_t *format_actual,
3238 uint32_t *usage,
3239 uint32_t *max_buffers)
3240{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003241 ALOGV("(%s): ", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003242 return obj(dev)->allocateStream(width, height, format, stream_ops,
3243 stream_id, format_actual, usage, max_buffers);
3244}
3245
3246
3247static int HAL2_device_register_stream_buffers(const struct camera2_device *dev,
3248 uint32_t stream_id,
3249 int num_buffers,
3250 buffer_handle_t *buffers)
3251{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003252 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003253 return obj(dev)->registerStreamBuffers(stream_id, num_buffers, buffers);
3254}
3255
3256static int HAL2_device_release_stream(
3257 const struct camera2_device *dev,
3258 uint32_t stream_id)
3259{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003260 ALOGD("DEBUG(%s)(id: %d):", __FUNCTION__, stream_id);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07003261 if (!g_camera_vaild)
3262 return 0;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003263 return obj(dev)->releaseStream(stream_id);
3264}
3265
3266static int HAL2_device_allocate_reprocess_stream(
3267 const struct camera2_device *dev,
3268 uint32_t width,
3269 uint32_t height,
3270 uint32_t format,
3271 const camera2_stream_in_ops_t *reprocess_stream_ops,
3272 // outputs
3273 uint32_t *stream_id,
3274 uint32_t *consumer_usage,
3275 uint32_t *max_buffers)
3276{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003277 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003278 return obj(dev)->allocateReprocessStream(width, height, format, reprocess_stream_ops,
3279 stream_id, consumer_usage, max_buffers);
3280}
3281
3282static int HAL2_device_release_reprocess_stream(
3283 const struct camera2_device *dev,
3284 uint32_t stream_id)
3285{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003286 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003287 return obj(dev)->releaseReprocessStream(stream_id);
3288}
3289
3290static int HAL2_device_trigger_action(const struct camera2_device *dev,
3291 uint32_t trigger_id,
3292 int ext1,
3293 int ext2)
3294{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003295 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003296 return obj(dev)->triggerAction(trigger_id, ext1, ext2);
3297}
3298
3299static int HAL2_device_set_notify_callback(const struct camera2_device *dev,
3300 camera2_notify_callback notify_cb,
3301 void *user)
3302{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003303 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003304 return obj(dev)->setNotifyCallback(notify_cb, user);
3305}
3306
3307static int HAL2_device_get_metadata_vendor_tag_ops(const struct camera2_device*dev,
3308 vendor_tag_query_ops_t **ops)
3309{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003310 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003311 return obj(dev)->getMetadataVendorTagOps(ops);
3312}
3313
3314static int HAL2_device_dump(const struct camera2_device *dev, int fd)
3315{
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003316 ALOGV("DEBUG(%s):", __FUNCTION__);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003317 return obj(dev)->dump(fd);
3318}
3319
3320
3321
3322
3323
3324static int HAL2_getNumberOfCameras()
3325{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003326 ALOGV("(%s): returning 2", __FUNCTION__);
3327 return 2;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003328}
3329
3330
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003331static int HAL2_getCameraInfo(int cameraId, struct camera_info *info)
3332{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003333 ALOGD("DEBUG(%s): cameraID: %d", __FUNCTION__, cameraId);
3334 static camera_metadata_t * mCameraInfo[2] = {NULL, NULL};
3335
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003336 status_t res;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003337
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003338 if (cameraId == 0)
3339 info->facing = CAMERA_FACING_BACK;
3340 else
3341 info->facing = CAMERA_FACING_FRONT;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003342 info->orientation = 0;
3343 info->device_version = HARDWARE_DEVICE_API_VERSION(2, 0);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003344 if (mCameraInfo[cameraId] == NULL) {
3345 res = constructStaticInfo(&(mCameraInfo[cameraId]), cameraId, true);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003346 if (res != OK) {
3347 ALOGE("%s: Unable to allocate static info: %s (%d)",
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003348 __FUNCTION__, strerror(-res), res);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003349 return res;
3350 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003351 res = constructStaticInfo(&(mCameraInfo[cameraId]), cameraId, false);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003352 if (res != OK) {
3353 ALOGE("%s: Unable to fill in static info: %s (%d)",
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003354 __FUNCTION__, strerror(-res), res);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003355 return res;
3356 }
3357 }
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003358 info->static_camera_characteristics = mCameraInfo[cameraId];
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003359 return NO_ERROR;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003360}
3361
3362#define SET_METHOD(m) m : HAL2_device_##m
3363
3364static camera2_device_ops_t camera2_device_ops = {
3365 SET_METHOD(set_request_queue_src_ops),
3366 SET_METHOD(notify_request_queue_not_empty),
3367 SET_METHOD(set_frame_queue_dst_ops),
3368 SET_METHOD(get_in_progress_count),
3369 SET_METHOD(flush_captures_in_progress),
3370 SET_METHOD(construct_default_request),
3371 SET_METHOD(allocate_stream),
3372 SET_METHOD(register_stream_buffers),
3373 SET_METHOD(release_stream),
3374 SET_METHOD(allocate_reprocess_stream),
3375 SET_METHOD(release_reprocess_stream),
3376 SET_METHOD(trigger_action),
3377 SET_METHOD(set_notify_callback),
3378 SET_METHOD(get_metadata_vendor_tag_ops),
3379 SET_METHOD(dump),
3380};
3381
3382#undef SET_METHOD
3383
3384
3385static int HAL2_camera_device_open(const struct hw_module_t* module,
3386 const char *id,
3387 struct hw_device_t** device)
3388{
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003389
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003390
3391 int cameraId = atoi(id);
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003392
Sungjoong Kangb5237e62012-07-27 07:39:05 -07003393 g_camera_vaild = false;
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003394 ALOGD("\n\n>>> I'm Samsung's CameraHAL_2(ID:%d) <<<\n\n", cameraId);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003395 if (cameraId < 0 || cameraId >= HAL2_getNumberOfCameras()) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003396 ALOGE("ERR(%s):Invalid camera ID %s", __FUNCTION__, id);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003397 return -EINVAL;
3398 }
3399
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003400 ALOGD("g_cam2_device : 0x%08x", (unsigned int)g_cam2_device);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003401 if (g_cam2_device) {
3402 if (obj(g_cam2_device)->getCameraId() == cameraId) {
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003403 ALOGV("DEBUG(%s):returning existing camera ID %s", __FUNCTION__, id);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003404 goto done;
3405 } else {
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003406
3407 while (g_cam2_device)
3408 usleep(10000);
3409 /*ALOGE("ERR(%s):Cannot open camera %d. camera %d is already running!",
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003410 __FUNCTION__, cameraId, obj(g_cam2_device)->getCameraId());
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003411 return -ENOSYS;*/
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003412 }
3413 }
3414
3415 g_cam2_device = (camera2_device_t *)malloc(sizeof(camera2_device_t));
Sungjoong Kang9dd63e12012-07-24 00:25:51 +09003416 ALOGD("g_cam2_device : 0x%08x", (unsigned int)g_cam2_device);
3417
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003418 if (!g_cam2_device)
3419 return -ENOMEM;
3420
3421 g_cam2_device->common.tag = HARDWARE_DEVICE_TAG;
3422 g_cam2_device->common.version = CAMERA_DEVICE_API_VERSION_2_0;
3423 g_cam2_device->common.module = const_cast<hw_module_t *>(module);
3424 g_cam2_device->common.close = HAL2_camera_device_close;
3425
3426 g_cam2_device->ops = &camera2_device_ops;
3427
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003428 ALOGV("DEBUG(%s):open camera2 %s", __FUNCTION__, id);
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003429
3430 g_cam2_device->priv = new ExynosCameraHWInterface2(cameraId, g_cam2_device);
3431
3432done:
3433 *device = (hw_device_t *)g_cam2_device;
Sungjoong Kang13d8c7b2012-07-14 10:20:39 +09003434 ALOGV("DEBUG(%s):opened camera2 %s (%p)", __FUNCTION__, id, *device);
Sungjoong Kangb5237e62012-07-27 07:39:05 -07003435 g_camera_vaild = true;
Jiyoung Shinc15a6b02012-06-05 01:08:14 -07003436
3437 return 0;
3438}
3439
3440
3441static hw_module_methods_t camera_module_methods = {
3442 open : HAL2_camera_device_open
3443};
3444
3445extern "C" {
3446 struct camera_module HAL_MODULE_INFO_SYM = {
3447 common : {
3448 tag : HARDWARE_MODULE_TAG,
3449 module_api_version : CAMERA_MODULE_API_VERSION_2_0,
3450 hal_api_version : HARDWARE_HAL_API_VERSION,
3451 id : CAMERA_HARDWARE_MODULE_ID,
3452 name : "Exynos Camera HAL2",
3453 author : "Samsung Corporation",
3454 methods : &camera_module_methods,
3455 dso: NULL,
3456 reserved: {0},
3457 },
3458 get_number_of_cameras : HAL2_getNumberOfCameras,
3459 get_camera_info : HAL2_getCameraInfo
3460 };
3461}
3462
3463}; // namespace android