blob: 56ec895927d6eba5541be07ed09115e4365c4580 [file] [log] [blame]
Iliyan Malchev6d016452013-03-27 16:27:56 -07001/*
2** Copyright (c) 2012 The Linux Foundation. All rights reserved.
3**
4** Licensed under the Apache License, Version 2.0 (the "License");
5** you may not use this file except in compliance with the License.
6** You may obtain a copy of the License at
7**
8** http://www.apache.org/licenses/LICENSE-2.0
9**
10** Unless required by applicable law or agreed to in writing, software
11** distributed under the License is distributed on an "AS IS" BASIS,
12** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13** See the License for the specific language governing permissions and
14** limitations under the License.
15*/
16
17/*#error uncomment this for compiler test!*/
18
19#define ALOG_NDEBUG 0
20#define ALOG_NIDEBUG 0
21#define LOG_TAG "QCameraHWI_Preview"
22#include <utils/Log.h>
23#include <utils/threads.h>
24#include <fcntl.h>
25#include <sys/mman.h>
26
27#include "QCameraHAL.h"
28#include "QCameraHWI.h"
29#include <gralloc_priv.h>
30#include <genlock.h>
31
32#define UNLIKELY(exp) __builtin_expect(!!(exp), 0)
33
34/* QCameraHWI_Preview class implementation goes here*/
35/* following code implement the preview mode's image capture & display logic of this class*/
36
37namespace android {
38
39// ---------------------------------------------------------------------------
40// Preview Callback
41// ---------------------------------------------------------------------------
42static void preview_notify_cb(mm_camera_ch_data_buf_t *frame,
43 void *user_data)
44{
45 QCameraStream_preview *pme = (QCameraStream_preview *)user_data;
46 mm_camera_ch_data_buf_t *bufs_used = 0;
47 ALOGV("%s: E", __func__);
48 /* for peview data, there is no queue, so directly use*/
49 if(pme==NULL) {
50 ALOGE("%s: X : Incorrect cookie",__func__);
51 /*Call buf done*/
52 return;
53 }
54
55 pme->processPreviewFrame(frame);
56 ALOGV("%s: X", __func__);
57}
58
59status_t QCameraStream_preview::setPreviewWindow(preview_stream_ops_t* window)
60{
61 status_t retVal = NO_ERROR;
62 ALOGE(" %s: E ", __FUNCTION__);
63 if( window == NULL) {
64 ALOGW(" Setting NULL preview window ");
65 /* TODO: Current preview window will be invalidated.
66 * Release all the buffers back */
67 // relinquishBuffers();
68 }
69 mDisplayLock.lock();
70 mPreviewWindow = window;
71 mDisplayLock.unlock();
72 ALOGV(" %s : X ", __FUNCTION__ );
73 return retVal;
74}
75
76status_t QCameraStream_preview::getBufferFromSurface() {
77 int err = 0;
78 int numMinUndequeuedBufs = 0;
79 int format = 0;
80 status_t ret = NO_ERROR;
81
82 ALOGI(" %s : E ", __FUNCTION__);
83
84 if( mPreviewWindow == NULL) {
85 ALOGE("%s: mPreviewWindow = NULL", __func__);
86 return INVALID_OPERATION;
87 }
88 cam_ctrl_dimension_t dim;
89
90 //mDisplayLock.lock();
91 cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);
92
93 format = mHalCamCtrl->getPreviewFormatInfo().Hal_format;
94 if(ret != NO_ERROR) {
95 ALOGE("%s: display format %d is not supported", __func__, dim.prev_format);
96 goto end;
97 }
98 numMinUndequeuedBufs = 0;
99 if(mPreviewWindow->get_min_undequeued_buffer_count) {
100 err = mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow, &numMinUndequeuedBufs);
101 if (err != 0) {
102 ALOGE("get_min_undequeued_buffer_count failed: %s (%d)",
103 strerror(-err), -err);
104 ret = UNKNOWN_ERROR;
105 goto end;
106 }
107 }
108 mHalCamCtrl->mPreviewMemoryLock.lock();
109 mHalCamCtrl->mPreviewMemory.buffer_count = kPreviewBufferCount + numMinUndequeuedBufs;;
110 err = mPreviewWindow->set_buffer_count(mPreviewWindow, mHalCamCtrl->mPreviewMemory.buffer_count );
111 if (err != 0) {
112 ALOGE("set_buffer_count failed: %s (%d)",
113 strerror(-err), -err);
114 ret = UNKNOWN_ERROR;
115 goto end;
116 }
117 err = mPreviewWindow->set_buffers_geometry(mPreviewWindow,
118 dim.display_width, dim.display_height, format);
119 if (err != 0) {
120 ALOGE("set_buffers_geometry failed: %s (%d)",
121 strerror(-err), -err);
122 ret = UNKNOWN_ERROR;
123 goto end;
124 }
125 err = mPreviewWindow->set_usage(mPreviewWindow,
126 GRALLOC_USAGE_PRIVATE_ADSP_HEAP |
127 GRALLOC_USAGE_PRIVATE_UNCACHED);
128 if(err != 0) {
129 /* set_usage error out */
130 ALOGE("%s: set_usage rc = %d", __func__, err);
131 ret = UNKNOWN_ERROR;
132 goto end;
133 }
134 for (int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) {
135 int stride;
136 err = mPreviewWindow->dequeue_buffer(mPreviewWindow,
137 &mHalCamCtrl->mPreviewMemory.buffer_handle[cnt],
138 &mHalCamCtrl->mPreviewMemory.stride[cnt]);
139 if(!err) {
140 err = mPreviewWindow->lock_buffer(this->mPreviewWindow,
141 mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
142
143 // lock the buffer using genlock
144 ALOGD("%s: camera call genlock_lock", __FUNCTION__);
145 if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t *)(*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]),
146 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
147 ALOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__);
148 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_UNLOCKED;
149 mHalCamCtrl->mPreviewMemoryLock.unlock();
150 return -EINVAL;
151 }
152 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_LOCKED;
153 } else
154 ALOGE("%s: dequeue_buffer idx = %d err = %d", __func__, cnt, err);
155
156 ALOGE("%s: dequeue buf: %u\n", __func__, (unsigned int)mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
157
158 if(err != 0) {
159 ALOGE("%s: dequeue_buffer failed: %s (%d)", __func__,
160 strerror(-err), -err);
161 ret = UNKNOWN_ERROR;
162 for(int i = 0; i < cnt; i++) {
163 ALOGD("%s: camera call genlock_unlock", __FUNCTION__);
164 if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[i]) {
165 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *)
166 (*(mHalCamCtrl->mPreviewMemory.buffer_handle[i])))) {
167 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
168 mHalCamCtrl->mPreviewMemoryLock.unlock();
169 return -EINVAL;
170 }
171 }
172 err = mPreviewWindow->cancel_buffer(mPreviewWindow,
173 mHalCamCtrl->mPreviewMemory.buffer_handle[i]);
174 mHalCamCtrl->mPreviewMemory.buffer_handle[i] = NULL;
175 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_UNLOCKED;
176 }
177 goto end;
178 }
179 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt] =
180 (struct private_handle_t *)(*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
181 mHalCamCtrl->mPreviewMemory.camera_memory[cnt] =
182 mHalCamCtrl->mGetMemory(mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd,
183 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size, 1, (void *)this);
184 ALOGE("%s: idx = %d, fd = %d, size = %d, offset = %d", __func__,
185 cnt, mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd,
186 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size,
187 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->offset);
188 }
189
190
191 memset(&mHalCamCtrl->mMetadata, 0, sizeof(mHalCamCtrl->mMetadata));
192 memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace));
193
194 ALOGI(" %s : X ",__FUNCTION__);
195end:
196 //mDisplayLock.unlock();
197 mHalCamCtrl->mPreviewMemoryLock.unlock();
198
199 return NO_ERROR;
200}
201
202status_t QCameraStream_preview::putBufferToSurface() {
203 int err = 0;
204 status_t ret = NO_ERROR;
205
206 ALOGI(" %s : E ", __FUNCTION__);
207
208 //mDisplayLock.lock();
209 mHalCamCtrl->mPreviewMemoryLock.lock();
210 for (int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) {
211 mHalCamCtrl->mPreviewMemory.camera_memory[cnt]->release(mHalCamCtrl->mPreviewMemory.camera_memory[cnt]);
212 if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[cnt]) {
213 ALOGD("%s: camera call genlock_unlock", __FUNCTION__);
214 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *)
215 (*(mHalCamCtrl->mPreviewMemory.buffer_handle[cnt])))) {
216 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
217 mHalCamCtrl->mPreviewMemoryLock.unlock();
218 return -EINVAL;
219 } else {
220 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_UNLOCKED;
221 }
222 }
223 err = mPreviewWindow->cancel_buffer(mPreviewWindow, mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
224 ALOGE(" put buffer %d successfully", cnt);
225 }
226 memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory));
227 mHalCamCtrl->mPreviewMemoryLock.unlock();
228 //mDisplayLock.unlock();
229 ALOGI(" %s : X ",__FUNCTION__);
230 return NO_ERROR;
231}
232
233void QCameraStream_preview::notifyROIEvent(fd_roi_t roi)
234{
235 switch (roi.type) {
236 case FD_ROI_TYPE_HEADER:
237 {
238 mDisplayLock.lock();
239 mNumFDRcvd = 0;
240 memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace));
241 mHalCamCtrl->mMetadata.faces = mHalCamCtrl->mFace;
242 mHalCamCtrl->mMetadata.number_of_faces = roi.d.hdr.num_face_detected;
243 if(mHalCamCtrl->mMetadata.number_of_faces > MAX_ROI)
244 mHalCamCtrl->mMetadata.number_of_faces = MAX_ROI;
245 mDisplayLock.unlock();
246
247 if (mHalCamCtrl->mMetadata.number_of_faces == 0) {
248 // Clear previous faces
249 mHalCamCtrl->mCallbackLock.lock();
250 camera_data_callback pcb = mHalCamCtrl->mDataCb;
251 mHalCamCtrl->mCallbackLock.unlock();
252
253 if (pcb && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA)){
254 ALOGE("%s: Face detection RIO callback", __func__);
255 pcb(CAMERA_MSG_PREVIEW_METADATA, NULL, 0, &mHalCamCtrl->mMetadata, mHalCamCtrl->mCallbackCookie);
256 }
257 }
258 }
259 break;
260 case FD_ROI_TYPE_DATA:
261 {
262 mDisplayLock.lock();
263 int idx = roi.d.data.idx;
264 if (idx >= mHalCamCtrl->mMetadata.number_of_faces) {
265 mDisplayLock.unlock();
266 ALOGE("%s: idx %d out of boundary %d", __func__, idx, mHalCamCtrl->mMetadata.number_of_faces);
267 break;
268 }
269
270 mHalCamCtrl->mFace[idx].id = roi.d.data.face.id;
271 mHalCamCtrl->mFace[idx].score = roi.d.data.face.score / 10; // keep within range 0~100
272
273 // top
274 mHalCamCtrl->mFace[idx].rect[0] =
275 roi.d.data.face.face_boundary.x*2000/mHalCamCtrl->mDimension.display_width - 1000;
276 //right
277 mHalCamCtrl->mFace[idx].rect[1] =
278 roi.d.data.face.face_boundary.y*2000/mHalCamCtrl->mDimension.display_height - 1000;
279 //bottom
280 mHalCamCtrl->mFace[idx].rect[2] = mHalCamCtrl->mFace[idx].rect[0] +
281 roi.d.data.face.face_boundary.dx*2000/mHalCamCtrl->mDimension.display_width;
282 //left
283 mHalCamCtrl->mFace[idx].rect[3] = mHalCamCtrl->mFace[idx].rect[1] +
284 roi.d.data.face.face_boundary.dy*2000/mHalCamCtrl->mDimension.display_height;
285
286 // Center of left eye
287 mHalCamCtrl->mFace[idx].left_eye[0] =
288 roi.d.data.face.left_eye_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000;
289 mHalCamCtrl->mFace[idx].left_eye[1] =
290 roi.d.data.face.left_eye_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000;
291
292 // Center of right eye
293 mHalCamCtrl->mFace[idx].right_eye[0] =
294 roi.d.data.face.right_eye_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000;
295 mHalCamCtrl->mFace[idx].right_eye[1] =
296 roi.d.data.face.right_eye_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000;
297
298 // Center of mouth
299 mHalCamCtrl->mFace[idx].mouth[0] =
300 roi.d.data.face.mouth_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000;
301 mHalCamCtrl->mFace[idx].mouth[1] =
302 roi.d.data.face.mouth_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000;
303
304 mHalCamCtrl->mFace[idx].smile_degree = roi.d.data.face.smile_degree;
305 mHalCamCtrl->mFace[idx].smile_score = roi.d.data.face.smile_confidence;
306 mHalCamCtrl->mFace[idx].blink_detected = roi.d.data.face.blink_detected;
307 mHalCamCtrl->mFace[idx].face_recognised = roi.d.data.face.is_face_recognised;
308 mHalCamCtrl->mFace[idx].gaze_angle = roi.d.data.face.gaze_angle;
309
310 /* newly added */
311 // upscale by 2 to recover from demaen downscaling
312 mHalCamCtrl->mFace[idx].updown_dir = roi.d.data.face.updown_dir*2;
313 mHalCamCtrl->mFace[idx].leftright_dir = roi.d.data.face.leftright_dir*2;
314 mHalCamCtrl->mFace[idx].roll_dir = roi.d.data.face.roll_dir*2;
315
316 mHalCamCtrl->mFace[idx].leye_blink = roi.d.data.face.left_blink;
317 mHalCamCtrl->mFace[idx].reye_blink = roi.d.data.face.right_blink;
318 mHalCamCtrl->mFace[idx].left_right_gaze = roi.d.data.face.left_right_gaze;
319 mHalCamCtrl->mFace[idx].top_bottom_gaze = roi.d.data.face.top_bottom_gaze;
320
321 ALOGE("%s: Face(%d, %d, %d, %d), leftEye(%d, %d), rightEye(%d, %d), mouth(%d, %d), smile(%d, %d), blinked(%d)", __func__,
322 mHalCamCtrl->mFace[idx].rect[0], mHalCamCtrl->mFace[idx].rect[1],
323 mHalCamCtrl->mFace[idx].rect[2], mHalCamCtrl->mFace[idx].rect[3],
324 mHalCamCtrl->mFace[idx].left_eye[0], mHalCamCtrl->mFace[idx].left_eye[1],
325 mHalCamCtrl->mFace[idx].right_eye[0], mHalCamCtrl->mFace[idx].right_eye[1],
326 mHalCamCtrl->mFace[idx].mouth[0], mHalCamCtrl->mFace[idx].mouth[1],
327 roi.d.data.face.smile_degree, roi.d.data.face.smile_confidence, roi.d.data.face.blink_detected);
328
329 mNumFDRcvd++;
330 mDisplayLock.unlock();
331
332 if (mNumFDRcvd == mHalCamCtrl->mMetadata.number_of_faces) {
333 mHalCamCtrl->mCallbackLock.lock();
334 camera_data_callback pcb = mHalCamCtrl->mDataCb;
335 mHalCamCtrl->mCallbackLock.unlock();
336
337 if (pcb && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA)){
338 ALOGE("%s: Face detection RIO callback with %d faces detected (score=%d)", __func__, mNumFDRcvd, mHalCamCtrl->mFace[idx].score);
339 pcb(CAMERA_MSG_PREVIEW_METADATA, NULL, 0, &mHalCamCtrl->mMetadata, mHalCamCtrl->mCallbackCookie);
340 }
341 }
342 }
343 break;
344 }
345}
346
347status_t QCameraStream_preview::initDisplayBuffers()
348{
349 status_t ret = NO_ERROR;
350 int width = 0; /* width of channel */
351 int height = 0; /* height of channel */
352 uint32_t frame_len = 0; /* frame planner length */
353 int buffer_num = 4; /* number of buffers for display */
354 const char *pmem_region;
355 uint8_t num_planes = 0;
356 uint32_t planes[VIDEO_MAX_PLANES];
357
358 cam_ctrl_dimension_t dim;
359
360 ALOGE("%s:BEGIN",__func__);
361 memset(&mHalCamCtrl->mMetadata, 0, sizeof(camera_frame_metadata_t));
362 mHalCamCtrl->mPreviewMemoryLock.lock();
363 memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory));
364 mHalCamCtrl->mPreviewMemoryLock.unlock();
365 memset(&mNotifyBuffer, 0, sizeof(mNotifyBuffer));
366
367 /* get preview size, by qury mm_camera*/
368 memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
369
370 memset(&(this->mDisplayStreamBuf),0, sizeof(this->mDisplayStreamBuf));
371
372 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
373 if (MM_CAMERA_OK != ret) {
374 ALOGE("%s: error - can't get camera dimension!", __func__);
375 ALOGE("%s: X", __func__);
376 return BAD_VALUE;
377 }else {
378 width = dim.display_width,
379 height = dim.display_height;
380 }
381
382 ret = getBufferFromSurface();
383 if(ret != NO_ERROR) {
384 ALOGE("%s: cannot get memory from surface texture client, ret = %d", __func__, ret);
385 return ret;
386 }
387
388 /* set 4 buffers for display */
389 memset(&mDisplayStreamBuf, 0, sizeof(mDisplayStreamBuf));
390 mHalCamCtrl->mPreviewMemoryLock.lock();
391 this->mDisplayStreamBuf.num = mHalCamCtrl->mPreviewMemory.buffer_count;
392 this->myMode=myMode; /*Need to assign this in constructor after translating from mask*/
393 num_planes = 2;
394 planes[0] = dim.display_frame_offset.mp[0].len;
395 planes[1] = dim.display_frame_offset.mp[1].len;
396 this->mDisplayStreamBuf.frame_len = dim.display_frame_offset.frame_len;
397
398 mDisplayBuf.preview.buf.mp = new mm_camera_mp_buf_t[mDisplayStreamBuf.num];
399 if (!mDisplayBuf.preview.buf.mp) {
400 ALOGE("%s Error allocating memory for mplanar struct ", __func__);
401 }
402 memset(mDisplayBuf.preview.buf.mp, 0,
403 mDisplayStreamBuf.num * sizeof(mm_camera_mp_buf_t));
404
405 /*allocate memory for the buffers*/
406 void *vaddr = NULL;
407 for(int i = 0; i < mDisplayStreamBuf.num; i++){
408 if (mHalCamCtrl->mPreviewMemory.private_buffer_handle[i] == NULL)
409 continue;
410 mDisplayStreamBuf.frame[i].fd = mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->fd;
411 mDisplayStreamBuf.frame[i].cbcr_off = planes[0];
412 mDisplayStreamBuf.frame[i].y_off = 0;
413 mDisplayStreamBuf.frame[i].path = OUTPUT_TYPE_P;
414 mHalCamCtrl->mPreviewMemory.addr_offset[i] =
415 mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->offset;
416 mDisplayStreamBuf.frame[i].buffer =
417 (long unsigned int)mHalCamCtrl->mPreviewMemory.camera_memory[i]->data;
418
419 ALOGE("%s: idx = %d, fd = %d, size = %d, cbcr_offset = %d, y_offset = %d, offset = %d, vaddr = 0x%x",
420 __func__, i,
421 mDisplayStreamBuf.frame[i].fd,
422 mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size,
423 mDisplayStreamBuf.frame[i].cbcr_off,
424 mDisplayStreamBuf.frame[i].y_off,
425 mHalCamCtrl->mPreviewMemory.addr_offset[i],
426 (uint32_t)mDisplayStreamBuf.frame[i].buffer);
427
428
429 mDisplayBuf.preview.buf.mp[i].frame = mDisplayStreamBuf.frame[i];
430 mDisplayBuf.preview.buf.mp[i].frame_offset = mHalCamCtrl->mPreviewMemory.addr_offset[i];
431 mDisplayBuf.preview.buf.mp[i].num_planes = num_planes;
432
433 /* Plane 0 needs to be set seperately. Set other planes
434 * in a loop. */
435 mDisplayBuf.preview.buf.mp[i].planes[0].length = planes[0];
436 mDisplayBuf.preview.buf.mp[i].planes[0].m.userptr = mDisplayStreamBuf.frame[i].fd;
437 mDisplayBuf.preview.buf.mp[i].planes[0].data_offset = 0;
438 mDisplayBuf.preview.buf.mp[i].planes[0].reserved[0] =
439 mDisplayBuf.preview.buf.mp[i].frame_offset;
440 for (int j = 1; j < num_planes; j++) {
441 mDisplayBuf.preview.buf.mp[i].planes[j].length = planes[j];
442 mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr =
443 mDisplayStreamBuf.frame[i].fd;
444 mDisplayBuf.preview.buf.mp[i].planes[j].data_offset = 0;
445 mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0] =
446 mDisplayBuf.preview.buf.mp[i].planes[j-1].reserved[0] +
447 mDisplayBuf.preview.buf.mp[i].planes[j-1].length;
448 }
449
450 for (int j = 0; j < num_planes; j++) {
451 ALOGE("Planes: %d length: %d userptr: %lu offset: %d\n",
452 j, mDisplayBuf.preview.buf.mp[i].planes[j].length,
453 mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr,
454 mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0]);
455 }
456
457 }/*end of for loop*/
458
459 /* register the streaming buffers for the channel*/
460 mDisplayBuf.ch_type = MM_CAMERA_CH_PREVIEW;
461 mDisplayBuf.preview.num = mDisplayStreamBuf.num;
462 mHalCamCtrl->mPreviewMemoryLock.unlock();
463 ALOGE("%s:END",__func__);
464 return NO_ERROR;
465
466end:
467 if (MM_CAMERA_OK == ret ) {
468 ALOGV("%s: X - NO_ERROR ", __func__);
469 return NO_ERROR;
470 }
471
472 ALOGV("%s: out of memory clean up", __func__);
473 /* release the allocated memory */
474
475 ALOGV("%s: X - BAD_VALUE ", __func__);
476 return BAD_VALUE;
477}
478
479void QCameraStream_preview::dumpFrameToFile(struct msm_frame* newFrame)
480{
481 int32_t enabled = 0;
482 int frm_num;
483 uint32_t skip_mode;
484 char value[PROPERTY_VALUE_MAX];
485 char buf[32];
486 int w, h;
487 static int count = 0;
488 cam_ctrl_dimension_t dim;
489 int file_fd;
490 int rc = 0;
491 int len;
492 unsigned long addr;
493 unsigned long * tmp = (unsigned long *)newFrame->buffer;
494 addr = *tmp;
495 status_t ret = cam_config_get_parm(mHalCamCtrl->mCameraId,
496 MM_CAMERA_PARM_DIMENSION, &dim);
497
498 w = dim.display_width;
499 h = dim.display_height;
500 len = (w * h)*3/2;
501 count++;
502 if(count < 100) {
503 snprintf(buf, sizeof(buf), "/data/mzhu%d.yuv", count);
504 file_fd = open(buf, O_RDWR | O_CREAT, 0777);
505
506 rc = write(file_fd, (const void *)addr, len);
507 ALOGE("%s: file='%s', vaddr_old=0x%x, addr_map = 0x%p, len = %d, rc = %d",
508 __func__, buf, (uint32_t)newFrame->buffer, (void *)addr, len, rc);
509 close(file_fd);
510 ALOGE("%s: dump %s, rc = %d, len = %d", __func__, buf, rc, len);
511 }
512}
513
514status_t QCameraStream_preview::processPreviewFrame(mm_camera_ch_data_buf_t *frame)
515{
516 ALOGV("%s",__func__);
517 int err = 0;
518 int msgType = 0;
519 camera_memory_t *data = NULL;
520 camera_frame_metadata_t *metadata = NULL;
521
522 Mutex::Autolock lock(mStopCallbackLock);
523 if(!mActive) {
524 ALOGE("Preview Stopped. Returning callback");
525 return NO_ERROR;
526 }
527 if(mHalCamCtrl==NULL) {
528 ALOGE("%s: X: HAL control object not set",__func__);
529 /*Call buf done*/
530 return BAD_VALUE;
531 }
532
533 mHalCamCtrl->mCallbackLock.lock();
534 camera_data_timestamp_callback rcb = mHalCamCtrl->mDataCbTimestamp;
535 void *rdata = mHalCamCtrl->mCallbackCookie;
536 mHalCamCtrl->mCallbackLock.unlock();
537
538 if (UNLIKELY(mHalCamCtrl->mDebugFps)) {
539 mHalCamCtrl->debugShowPreviewFPS();
540 }
541 //dumpFrameToFile(frame->def.frame);
542 mHalCamCtrl->dumpFrameToFile(frame->def.frame, HAL_DUMP_FRM_PREVIEW);
543
544 nsecs_t timeStamp = systemTime();
545
546 mHalCamCtrl->mPreviewMemoryLock.lock();
547 mNotifyBuffer[frame->def.idx] = *frame;
548 // mzhu fix me, need to check meta data also.
549
550 ALOGI("Enqueue buf handle %p\n",
551 mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
552 ALOGD("%s: camera call genlock_unlock", __FUNCTION__);
553 if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx]) {
554 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t*)
555 (*mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]))) {
556 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
557 mHalCamCtrl->mPreviewMemoryLock.unlock();
558 return -EINVAL;
559 } else {
560 mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx] = BUFFER_UNLOCKED;
561 }
562 } else {
563 ALOGE("%s: buffer to be enqueued is not locked", __FUNCTION__);
564 mHalCamCtrl->mPreviewMemoryLock.unlock();
565 return -EINVAL;
566 }
567 err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow,
568 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
569 if(err != 0) {
570 ALOGE("%s: enqueue_buffer failed, err = %d", __func__, err);
571 }
572 buffer_handle_t *buffer_handle = NULL;
573 int tmp_stride = 0;
574 err = this->mPreviewWindow->dequeue_buffer(this->mPreviewWindow,
575 &buffer_handle, &tmp_stride);
576 if (err == NO_ERROR && buffer_handle != NULL) {
577 err = this->mPreviewWindow->lock_buffer(this->mPreviewWindow, buffer_handle);
578 ALOGD("%s: camera call genlock_lock", __FUNCTION__);
579 if (GENLOCK_FAILURE == genlock_lock_buffer((native_handle_t*)(*buffer_handle), GENLOCK_WRITE_LOCK,
580 GENLOCK_MAX_TIMEOUT)) {
581 ALOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__);
582 mHalCamCtrl->mPreviewMemoryLock.unlock();
583 return -EINVAL;
584 }
585 for(int i = 0; i < mHalCamCtrl->mPreviewMemory.buffer_count; i++) {
586 ALOGD("h1: %p h2: %p\n", mHalCamCtrl->mPreviewMemory.buffer_handle[i], buffer_handle);
587 if(mHalCamCtrl->mPreviewMemory.buffer_handle[i] == buffer_handle) {
588 mm_camera_ch_data_buf_t tmp_frame;
589 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_LOCKED;
590 if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, &mNotifyBuffer[i])) {
591 ALOGD("BUF DONE FAILED");
592 mHalCamCtrl->mPreviewMemoryLock.unlock();
593 return BAD_VALUE;
594 }
595 break;
596 }
597 }
598 } else
599 ALOGE("%s: error in dequeue_buffer, enqueue_buffer idx = %d, no free buffer now", __func__, frame->def.idx);
600 /* Save the last displayed frame. We'll be using it to fill the gap between
601 when preview stops and postview start during snapshot.*/
602 mLastQueuedFrame = &(mDisplayStreamBuf.frame[frame->def.idx]);
603 mHalCamCtrl->mPreviewMemoryLock.unlock();
604
605 mHalCamCtrl->mCallbackLock.lock();
606 camera_data_callback pcb = mHalCamCtrl->mDataCb;
607 mHalCamCtrl->mCallbackLock.unlock();
608 ALOGD("Message enabled = 0x%x", mHalCamCtrl->mMsgEnabled);
609
610 if (pcb != NULL) {
611 //Sending preview callback if corresponding Msgs are enabled
612 if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) {
613 msgType |= CAMERA_MSG_PREVIEW_FRAME;
614 data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx];//mPreviewHeap->mBuffers[frame->def.idx];
615 } else {
616 data = NULL;
617 }
618 if(msgType) {
619 mStopCallbackLock.unlock();
620 pcb(msgType, data, 0, metadata, mHalCamCtrl->mCallbackCookie);
621 }
622 ALOGD("end of cb");
623 }
624 if(rcb != NULL)
625 {
626 if (mHalCamCtrl->mStoreMetaDataInFrame)
627 {
628 mStopCallbackLock.unlock();
629 if(mHalCamCtrl->mStartRecording == true &&( mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME))
630 rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
631 mHalCamCtrl->mRecordingMemory.metadata_memory[frame->def.idx],
632 0, mHalCamCtrl->mCallbackCookie);
633 }
634 else
635 {
636 if(mHalCamCtrl->mStartRecording == true &&( mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME))
637 {
638 mStopCallbackLock.unlock();
639 rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
640 mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx],
641 0, mHalCamCtrl->mCallbackCookie);
642 }
643 }
644 }
645
646 /* Save the last displayed frame. We'll be using it to fill the gap between
647 when preview stops and postview start during snapshot.*/
648 //mLastQueuedFrame = frame->def.frame;
649/*
650 if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, frame))
651 {
652 ALOGE("BUF DONE FAILED");
653 return BAD_VALUE;
654 }
655*/
656 return NO_ERROR;
657}
658
659// ---------------------------------------------------------------------------
660// QCameraStream_preview
661// ---------------------------------------------------------------------------
662
663QCameraStream_preview::
664QCameraStream_preview(int cameraId, camera_mode_t mode)
665 : QCameraStream(cameraId,mode),
666 mLastQueuedFrame(NULL),
667 mNumFDRcvd(0)
668 {
669 mHalCamCtrl = NULL;
670 ALOGE("%s: E", __func__);
671 ALOGE("%s: X", __func__);
672 }
673// ---------------------------------------------------------------------------
674// QCameraStream_preview
675// ---------------------------------------------------------------------------
676
677QCameraStream_preview::~QCameraStream_preview() {
678 ALOGV("%s: E", __func__);
679 if(mActive) {
680 stop();
681 }
682 if(mInit) {
683 release();
684 }
685 mInit = false;
686 mActive = false;
687 ALOGV("%s: X", __func__);
688
689}
690// ---------------------------------------------------------------------------
691// QCameraStream_preview
692// ---------------------------------------------------------------------------
693
694status_t QCameraStream_preview::init() {
695
696 status_t ret = NO_ERROR;
697 ALOGV("%s: E", __func__);
698
699 ret = QCameraStream::initChannel (mCameraId, MM_CAMERA_CH_PREVIEW_MASK);
700 if (NO_ERROR!=ret) {
701 ALOGE("%s E: can't init native cammera preview ch\n",__func__);
702 return ret;
703 }
704
705 ALOGE("Debug : %s : initChannel",__func__);
706 /* register a notify into the mmmm_camera_t object*/
707 (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW,
708 preview_notify_cb, MM_CAMERA_REG_BUF_CB_INFINITE, 0, this);
709 ALOGE("Debug : %s : cam_evt_register_buf_notify",__func__);
710 buffer_handle_t *buffer_handle = NULL;
711 int tmp_stride = 0;
712 mInit = true;
713 return ret;
714}
715// ---------------------------------------------------------------------------
716// QCameraStream_preview
717// ---------------------------------------------------------------------------
718
719status_t QCameraStream_preview::start()
720{
721 ALOGV("%s: E", __func__);
722 status_t ret = NO_ERROR;
723 mm_camera_reg_buf_t *reg_buf=&mDisplayBuf;
724
725 Mutex::Autolock lock(mStopCallbackLock);
726
727 /* call start() in parent class to start the monitor thread*/
728 //QCameraStream::start ();
729 setFormat(MM_CAMERA_CH_PREVIEW_MASK);
730
731 if(NO_ERROR!=initDisplayBuffers()){
732 return BAD_VALUE;
733 }
734 ALOGE("Debug : %s : initDisplayBuffers",__func__);
735 ret = cam_config_prepare_buf(mCameraId, reg_buf);
736 ALOGE("Debug : %s : cam_config_prepare_buf",__func__);
737 if(ret != MM_CAMERA_OK) {
738 ALOGV("%s:reg preview buf err=%d\n", __func__, ret);
739 ret = BAD_VALUE;
740 }else
741 ret = NO_ERROR;
742
743 /* For preview, the OP_MODE we set is dependent upon whether we are
744 starting camera or camcorder. For snapshot, anyway we disable preview.
745 However, for ZSL we need to set OP_MODE to OP_MODE_ZSL and not
746 OP_MODE_VIDEO. We'll set that for now in CamCtrl. So in case of
747 ZSL we skip setting Mode here */
748
749 if (!(myMode & CAMERA_ZSL_MODE)) {
750 ALOGE("Setting OP MODE to MM_CAMERA_OP_MODE_VIDEO");
751 mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_VIDEO;
752 ret = cam_config_set_parm (mCameraId, MM_CAMERA_PARM_OP_MODE,
753 &op_mode);
754 ALOGE("OP Mode Set");
755
756 if(MM_CAMERA_OK != ret) {
757 ALOGE("%s: X :set mode MM_CAMERA_OP_MODE_VIDEO err=%d\n", __func__, ret);
758 return BAD_VALUE;
759 }
760 }else {
761 ALOGE("Setting OP MODE to MM_CAMERA_OP_MODE_ZSL");
762 mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_ZSL;
763 ret = cam_config_set_parm (mCameraId, MM_CAMERA_PARM_OP_MODE,
764 &op_mode);
765 if(MM_CAMERA_OK != ret) {
766 ALOGE("%s: X :set mode MM_CAMERA_OP_MODE_ZSL err=%d\n", __func__, ret);
767 return BAD_VALUE;
768 }
769 }
770
771 /* call mm_camera action start(...) */
772 ALOGE("Starting Preview/Video Stream. ");
773 ret = cam_ops_action(mCameraId, TRUE, MM_CAMERA_OPS_PREVIEW, 0);
774
775 if (MM_CAMERA_OK != ret) {
776 ALOGE ("%s: preview streaming start err=%d\n", __func__, ret);
777 return BAD_VALUE;
778 }
779
780 ALOGE("Debug : %s : Preview streaming Started",__func__);
781 ret = NO_ERROR;
782
783 mActive = true;
784 ALOGE("%s: X", __func__);
785 return NO_ERROR;
786 }
787
788
789// ---------------------------------------------------------------------------
790// QCameraStream_preview
791// ---------------------------------------------------------------------------
792 void QCameraStream_preview::stop() {
793 ALOGE("%s: E", __func__);
794 int ret=MM_CAMERA_OK;
795
796 if(!mActive) {
797 return;
798 }
799 mActive = false;
800 Mutex::Autolock lock(mStopCallbackLock);
801 /* unregister the notify fn from the mmmm_camera_t object*/
802
803 /* call stop() in parent class to stop the monitor thread*/
804 ret = cam_ops_action(mCameraId, FALSE, MM_CAMERA_OPS_PREVIEW, 0);
805 if(MM_CAMERA_OK != ret) {
806 ALOGE ("%s: camera preview stop err=%d\n", __func__, ret);
807 }
808 ALOGE("Debug : %s : Preview streaming Stopped",__func__);
809 ret = cam_config_unprepare_buf(mCameraId, MM_CAMERA_CH_PREVIEW);
810 if(ret != MM_CAMERA_OK) {
811 ALOGE("%s:Unreg preview buf err=%d\n", __func__, ret);
812 //ret = BAD_VALUE;
813 }
814
815 ALOGE("Debug : %s : Buffer Unprepared",__func__);
816 if (mDisplayBuf.preview.buf.mp != NULL) {
817 delete[] mDisplayBuf.preview.buf.mp;
818 }
819 /*free camera_memory handles and return buffer back to surface*/
820 putBufferToSurface();
821
822 ALOGE("%s: X", __func__);
823
824 }
825// ---------------------------------------------------------------------------
826// QCameraStream_preview
827// ---------------------------------------------------------------------------
828 void QCameraStream_preview::release() {
829
830 ALOGE("%s : BEGIN",__func__);
831 int ret=MM_CAMERA_OK,i;
832
833 if(!mInit)
834 {
835 ALOGE("%s : Stream not Initalized",__func__);
836 return;
837 }
838
839 if(mActive) {
840 this->stop();
841 }
842
843 ret= QCameraStream::deinitChannel(mCameraId, MM_CAMERA_CH_PREVIEW);
844 ALOGE("Debug : %s : De init Channel",__func__);
845 if(ret != MM_CAMERA_OK) {
846 ALOGE("%s:Deinit preview channel failed=%d\n", __func__, ret);
847 //ret = BAD_VALUE;
848 }
849
850 (void)cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW,
851 NULL,
852 (mm_camera_register_buf_cb_type_t)NULL,
853 NULL,
854 NULL);
855 mInit = false;
856 ALOGE("%s: END", __func__);
857
858 }
859
860QCameraStream*
861QCameraStream_preview::createInstance(int cameraId,
862 camera_mode_t mode)
863{
864 QCameraStream* pme = new QCameraStream_preview(cameraId, mode);
865 return pme;
866}
867// ---------------------------------------------------------------------------
868// QCameraStream_preview
869// ---------------------------------------------------------------------------
870
871void QCameraStream_preview::deleteInstance(QCameraStream *p)
872{
873 if (p){
874 ALOGV("%s: BEGIN", __func__);
875 p->release();
876 delete p;
877 p = NULL;
878 ALOGV("%s: END", __func__);
879 }
880}
881
882
883/* Temp helper function */
884void *QCameraStream_preview::getLastQueuedFrame(void)
885{
886 return mLastQueuedFrame;
887}
888
889status_t QCameraStream_preview::initPreviewOnlyBuffers()
890{
891 /*1. for 7x27a, this shall not called;
892 2. this file shall be removed ASAP
893 so put a dummy function to just pass the compile*/
894 return INVALID_OPERATION;
895}
896
897// ---------------------------------------------------------------------------
898// No code beyone this line
899// ---------------------------------------------------------------------------
900}; // namespace android