1 /*
2 ** Copyright (c) 2011-2012,2015 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 LOG_TAG "QCameraHWI_Preview"
20 #include <utils/Log.h>
21 #include <utils/threads.h>
22 #include <fcntl.h>
23 #include <sys/mman.h>
24 #include "QCameraHAL.h"
25 #include "QCameraHWI.h"
26 #include <genlock.h>
27 #include <gralloc_priv.h>
28
29 #define UNLIKELY(exp) __builtin_expect(!!(exp), 0)
30
31 /* QCameraHWI_Preview class implementation goes here*/
32 /* following code implement the preview mode's image capture & display logic of this class*/
33
34 namespace android {
35
36 // ---------------------------------------------------------------------------
37 // Preview Callback
38 // ---------------------------------------------------------------------------
preview_notify_cb(mm_camera_ch_data_buf_t * frame,void * user_data)39 static void preview_notify_cb(mm_camera_ch_data_buf_t *frame,
40 void *user_data)
41 {
42 QCameraStream_preview *pme = (QCameraStream_preview *)user_data;
43 mm_camera_ch_data_buf_t *bufs_used = 0;
44 ALOGV("%s: E", __func__);
45 /* for peview data, there is no queue, so directly use*/
46 if(pme==NULL) {
47 ALOGE("%s: X : Incorrect cookie",__func__);
48 /*Call buf done*/
49 return;
50 }
51
52 pme->processPreviewFrame(frame);
53 ALOGV("%s: X", __func__);
54 }
55
setPreviewWindow(preview_stream_ops_t * window)56 status_t QCameraStream_preview::setPreviewWindow(preview_stream_ops_t* window)
57 {
58 status_t retVal = NO_ERROR;
59 ALOGV(" %s: E ", __FUNCTION__);
60 if( window == NULL) {
61 ALOGW(" Setting NULL preview window ");
62 /* TODO: Current preview window will be invalidated.
63 * Release all the buffers back */
64 // relinquishBuffers();
65 }
66 Mutex::Autolock lock(mStopCallbackLock);
67 mPreviewWindow = window;
68 ALOGV(" %s : X ", __FUNCTION__ );
69 return retVal;
70 }
71
getBufferFromSurface()72 status_t QCameraStream_preview::getBufferFromSurface()
73 {
74 int err = 0;
75 int numMinUndequeuedBufs = 0;
76 int format = 0;
77 status_t ret = NO_ERROR;
78 int gralloc_usage;
79
80 ALOGV(" %s : E ", __FUNCTION__);
81
82 if( mPreviewWindow == NULL) {
83 ALOGE("%s: mPreviewWindow = NULL", __func__);
84 return INVALID_OPERATION;
85 }
86 cam_ctrl_dimension_t dim;
87
88 //mDisplayLock.lock();
89 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);
90
91 format = mHalCamCtrl->getPreviewFormatInfo().Hal_format;
92 if(ret != NO_ERROR) {
93 ALOGE("%s: display format %d is not supported", __func__, dim.prev_format);
94 goto end;
95 }
96 numMinUndequeuedBufs = 0;
97 if(mPreviewWindow->get_min_undequeued_buffer_count) {
98 err = mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow, &numMinUndequeuedBufs);
99 if (err != 0) {
100 ALOGE("get_min_undequeued_buffer_count failed: %s (%d)",
101 strerror(-err), -err);
102 ret = UNKNOWN_ERROR;
103 goto end;
104 }
105 }
106 mHalCamCtrl->mPreviewMemoryLock.lock();
107 mHalCamCtrl->mPreviewMemory.buffer_count = kPreviewBufferCount + numMinUndequeuedBufs;
108 if(mHalCamCtrl->isZSLMode()) {
109 if(mHalCamCtrl->getZSLQueueDepth() > numMinUndequeuedBufs)
110 mHalCamCtrl->mPreviewMemory.buffer_count +=
111 mHalCamCtrl->getZSLQueueDepth() - numMinUndequeuedBufs;
112 }
113 err = mPreviewWindow->set_buffer_count(mPreviewWindow, mHalCamCtrl->mPreviewMemory.buffer_count );
114 if (err != 0) {
115 ALOGE("set_buffer_count failed: %s (%d)",
116 strerror(-err), -err);
117 ret = UNKNOWN_ERROR;
118 goto end;
119 }
120 err = mPreviewWindow->set_buffers_geometry(mPreviewWindow,
121 dim.display_width, dim.display_height, format);
122 if (err != 0) {
123 ALOGE("set_buffers_geometry failed: %s (%d)",
124 strerror(-err), -err);
125 ret = UNKNOWN_ERROR;
126 goto end;
127 }
128
129 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_VFE_OUTPUT_ENABLE, &mVFEOutputs);
130 if(ret != MM_CAMERA_OK) {
131 ALOGE("get parm MM_CAMERA_PARM_VFE_OUTPUT_ENABLE failed");
132 ret = BAD_VALUE;
133 goto end;
134 }
135
136 //as software encoder is used to encode 720p, to enhance the performance
137 //cashed pmem is used here
138 if(mVFEOutputs == 1 && dim.display_height == 720)
139 gralloc_usage = GRALLOC_USAGE_HW_CAMERA_WRITE | CAMERA_GRALLOC_HEAP_ID | CAMERA_GRALLOC_FALLBACK_HEAP_ID;
140 else
141 gralloc_usage = GRALLOC_USAGE_HW_CAMERA_WRITE | CAMERA_GRALLOC_HEAP_ID | CAMERA_GRALLOC_FALLBACK_HEAP_ID |
142 CAMERA_GRALLOC_CACHING_ID;
143 err = mPreviewWindow->set_usage(mPreviewWindow, gralloc_usage);
144 if(err != 0) {
145 /* set_usage error out */
146 ALOGE("%s: set_usage rc = %d", __func__, err);
147 ret = UNKNOWN_ERROR;
148 goto end;
149 }
150 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_HFR_FRAME_SKIP, &mHFRFrameSkip);
151 if(ret != MM_CAMERA_OK) {
152 ALOGE("get parm MM_CAMERA_PARM_HFR_FRAME_SKIP failed");
153 ret = BAD_VALUE;
154 goto end;
155 }
156 for (int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) {
157 int stride;
158 err = mPreviewWindow->dequeue_buffer(mPreviewWindow,
159 &mHalCamCtrl->mPreviewMemory.buffer_handle[cnt],
160 &mHalCamCtrl->mPreviewMemory.stride[cnt]);
161 if(!err) {
162 ALOGV("%s: dequeue buf hdl =%p", __func__, *mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
163 err = mPreviewWindow->lock_buffer(this->mPreviewWindow,
164 mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
165 // lock the buffer using genlock
166 ALOGV("%s: camera call genlock_lock, hdl=%p", __FUNCTION__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]));
167 if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t *)(*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]),
168 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
169 ALOGV("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__);
170 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_UNLOCKED;
171 //mHalCamCtrl->mPreviewMemoryLock.unlock();
172 //return -EINVAL;
173 } else {
174 ALOGV("%s: genlock_lock_buffer hdl =%p", __FUNCTION__, *mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
175 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_LOCKED;
176 }
177 } else {
178 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_NOT_OWNED;
179 ALOGV("%s: dequeue_buffer idx = %d err = %d", __func__, cnt, err);
180 }
181
182 ALOGV("%s: dequeue buf: %p\n", __func__, mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
183
184 if(err != 0) {
185 ALOGE("%s: dequeue_buffer failed: %s (%d)", __func__,
186 strerror(-err), -err);
187 ret = UNKNOWN_ERROR;
188 for(int i = 0; i < cnt; i++) {
189 if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[i]) {
190 ALOGV("%s: camera call genlock_unlock", __FUNCTION__);
191 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *)
192 (*(mHalCamCtrl->mPreviewMemory.buffer_handle[i])))) {
193 ALOGE("%s: genlock_unlock_buffer failed: hdl =%p", __FUNCTION__, (*(mHalCamCtrl->mPreviewMemory.buffer_handle[i])) );
194 //mHalCamCtrl->mPreviewMemoryLock.unlock();
195 //return -EINVAL;
196 } else {
197 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_UNLOCKED;
198 }
199 }
200 if( mHalCamCtrl->mPreviewMemory.local_flag[i] != BUFFER_NOT_OWNED) {
201 err = mPreviewWindow->cancel_buffer(mPreviewWindow,
202 mHalCamCtrl->mPreviewMemory.buffer_handle[i]);
203 }
204 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_NOT_OWNED;
205 ALOGV("%s: cancel_buffer: hdl =%p", __func__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[i]));
206 mHalCamCtrl->mPreviewMemory.buffer_handle[i] = NULL;
207 }
208 memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory));
209 goto end;
210 }
211
212 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt] =
213 (struct private_handle_t *)(*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
214 #ifdef USE_ION
215 mHalCamCtrl->mPreviewMemory.main_ion_fd[cnt] = open("/dev/ion", O_RDONLY);
216 if (mHalCamCtrl->mPreviewMemory.main_ion_fd[cnt] < 0) {
217 ALOGE("%s: failed: could not open ion device\n", __func__);
218 } else {
219 mHalCamCtrl->mPreviewMemory.ion_info_fd[cnt].fd =
220 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd;
221 if (ioctl(mHalCamCtrl->mPreviewMemory.main_ion_fd[cnt],
222 ION_IOC_IMPORT, &mHalCamCtrl->mPreviewMemory.ion_info_fd[cnt]) < 0)
223 ALOGE("ION import failed\n");
224 }
225 #endif
226 mHalCamCtrl->mPreviewMemory.camera_memory[cnt] =
227 mHalCamCtrl->mGetMemory(mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd,
228 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size, 1, (void *)this);
229 ALOGV("%s: idx = %d, fd = %d, size = %d, offset = %d", __func__,
230 cnt, mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd,
231 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size,
232 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->offset);
233 }
234
235 //Cancel min_undequeued_buffer buffers back to the window
236 for (int i = 0; i < numMinUndequeuedBufs; i ++) {
237 if( mHalCamCtrl->mPreviewMemory.local_flag[i] != BUFFER_NOT_OWNED) {
238 err = mPreviewWindow->cancel_buffer(mPreviewWindow, mHalCamCtrl->mPreviewMemory.buffer_handle[i]);
239 }
240 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_NOT_OWNED;
241 }
242
243 memset(&mHalCamCtrl->mMetadata, 0, sizeof(mHalCamCtrl->mMetadata));
244 memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace));
245
246 ALOGV(" %s : X ",__FUNCTION__);
247 end:
248 //mDisplayLock.unlock();
249 mHalCamCtrl->mPreviewMemoryLock.unlock();
250
251 return ret;
252 }
253
putBufferToSurface()254 status_t QCameraStream_preview::putBufferToSurface() {
255 int err = 0;
256 status_t ret = NO_ERROR;
257
258 ALOGV(" %s : E ", __FUNCTION__);
259
260 mHalCamCtrl->mPreviewMemoryLock.lock();
261 for (int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) {
262 if (cnt < mHalCamCtrl->mPreviewMemory.buffer_count) {
263 if (NO_ERROR != mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW, cnt, mCameraId,
264 CAM_SOCK_MSG_TYPE_FD_UNMAPPING)) {
265 ALOGE("%s: unmapping Preview Buffer", __func__);
266 }
267 if(mHalCamCtrl->isZSLMode()) {
268 if (NO_ERROR != mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL, cnt, mCameraId,
269 CAM_SOCK_MSG_TYPE_FD_UNMAPPING)) {
270 ALOGE("%s: unmapping Thumbnail Buffer for ZSL", __func__);
271 }
272 }
273 }
274
275 mHalCamCtrl->mPreviewMemory.camera_memory[cnt]->release(mHalCamCtrl->mPreviewMemory.camera_memory[cnt]);
276 #ifdef USE_ION
277 struct ion_handle_data ion_handle;
278 ion_handle.handle = mHalCamCtrl->mPreviewMemory.ion_info_fd[cnt].handle;
279 if (ioctl(mHalCamCtrl->mPreviewMemory.main_ion_fd[cnt], ION_IOC_FREE, &ion_handle)
280 < 0)
281 ALOGE("%s: ion free failed\n", __func__);
282 close(mHalCamCtrl->mPreviewMemory.main_ion_fd[cnt]);
283 #endif
284 if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[cnt]) {
285 ALOGV("%s: camera call genlock_unlock", __FUNCTION__);
286 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *)
287 (*(mHalCamCtrl->mPreviewMemory.buffer_handle[cnt])))) {
288 ALOGE("%s: genlock_unlock_buffer failed, handle =%p", __FUNCTION__, (*(mHalCamCtrl->mPreviewMemory.buffer_handle[cnt])));
289 continue;
290 //mHalCamCtrl->mPreviewMemoryLock.unlock();
291 //return -EINVAL;
292 } else {
293
294 ALOGV("%s: genlock_unlock_buffer, handle =%p", __FUNCTION__, (*(mHalCamCtrl->mPreviewMemory.buffer_handle[cnt])));
295 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_UNLOCKED;
296 }
297 }
298 if( mHalCamCtrl->mPreviewMemory.local_flag[cnt] != BUFFER_NOT_OWNED) {
299 err = mPreviewWindow->cancel_buffer(mPreviewWindow, mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
300 ALOGV("%s: cancel_buffer: hdl =%p", __func__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]));
301 }
302 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_NOT_OWNED;
303
304 ALOGV(" put buffer %d successfully", cnt);
305 }
306
307 if (mDisplayBuf.preview.buf.mp != NULL) {
308 delete[] mDisplayBuf.preview.buf.mp;
309 mDisplayBuf.preview.buf.mp = NULL;
310 }
311
312 mHalCamCtrl->mPreviewMemoryLock.unlock();
313 memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory));
314 ALOGV(" %s : X ",__FUNCTION__);
315 return NO_ERROR;
316 }
317
notifyROIEvent(fd_roi_t roi)318 void QCameraStream_preview::notifyROIEvent(fd_roi_t roi)
319 {
320 camera_memory_t *data = mHalCamCtrl->mGetMemory(-1, 1, 1, NULL);
321 switch (roi.type) {
322 case FD_ROI_TYPE_HEADER:
323 {
324 mDisplayLock.lock();
325 mNumFDRcvd = 0;
326 memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace));
327 mHalCamCtrl->mMetadata.faces = mHalCamCtrl->mFace;
328 mHalCamCtrl->mMetadata.number_of_faces = roi.d.hdr.num_face_detected;
329 if(mHalCamCtrl->mMetadata.number_of_faces > MAX_ROI)
330 mHalCamCtrl->mMetadata.number_of_faces = MAX_ROI;
331 mDisplayLock.unlock();
332
333 if (mHalCamCtrl->mMetadata.number_of_faces == 0) {
334 // Clear previous faces
335 mHalCamCtrl->mCallbackLock.lock();
336 camera_data_callback pcb = mHalCamCtrl->mDataCb;
337 mHalCamCtrl->mCallbackLock.unlock();
338
339 if (pcb && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA)){
340 ALOGV("%s: Face detection RIO callback", __func__);
341 pcb(CAMERA_MSG_PREVIEW_METADATA, data, 0, &mHalCamCtrl->mMetadata, mHalCamCtrl->mCallbackCookie);
342 }
343 }
344 }
345 break;
346 case FD_ROI_TYPE_DATA:
347 {
348 #if 1
349 mDisplayLock.lock();
350 int idx = roi.d.data.idx;
351 if (idx >= mHalCamCtrl->mMetadata.number_of_faces) {
352 mDisplayLock.unlock();
353 ALOGE("%s: idx %d out of boundary %d", __func__, idx, mHalCamCtrl->mMetadata.number_of_faces);
354 break;
355 }
356
357 mHalCamCtrl->mFace[idx].id = roi.d.data.face.id;
358 mHalCamCtrl->mFace[idx].score = roi.d.data.face.score;
359
360 // top
361 mHalCamCtrl->mFace[idx].rect[0] =
362 roi.d.data.face.face_boundary.x*2000/mHalCamCtrl->mDimension.display_width - 1000;
363 //right
364 mHalCamCtrl->mFace[idx].rect[1] =
365 roi.d.data.face.face_boundary.y*2000/mHalCamCtrl->mDimension.display_height - 1000;
366 //bottom
367 mHalCamCtrl->mFace[idx].rect[2] = mHalCamCtrl->mFace[idx].rect[0] +
368 roi.d.data.face.face_boundary.dx*2000/mHalCamCtrl->mDimension.display_width;
369 //left
370 mHalCamCtrl->mFace[idx].rect[3] = mHalCamCtrl->mFace[idx].rect[1] +
371 roi.d.data.face.face_boundary.dy*2000/mHalCamCtrl->mDimension.display_height;
372
373 // Center of left eye
374 mHalCamCtrl->mFace[idx].left_eye[0] =
375 roi.d.data.face.left_eye_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000;
376 mHalCamCtrl->mFace[idx].left_eye[1] =
377 roi.d.data.face.left_eye_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000;
378
379 // Center of right eye
380 mHalCamCtrl->mFace[idx].right_eye[0] =
381 roi.d.data.face.right_eye_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000;
382 mHalCamCtrl->mFace[idx].right_eye[1] =
383 roi.d.data.face.right_eye_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000;
384 #if 0
385 // Center of mouth
386 mHalCamCtrl->mFace[idx].mouth[0] =
387 roi.d.data.face.mouth_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000;
388 mHalCamCtrl->mFace[idx].mouth[1] =
389 roi.d.data.face.mouth_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000;
390
391 mHalCamCtrl->mFace[idx].smile_degree = roi.d.data.face.smile_degree;
392 mHalCamCtrl->mFace[idx].smile_score = roi.d.data.face.smile_confidence;
393 mHalCamCtrl->mFace[idx].blink_detected = roi.d.data.face.blink_detected;
394 mHalCamCtrl->mFace[idx].face_recognised = roi.d.data.face.is_face_recognised;
395 mHalCamCtrl->mFace[idx].gaze_angle = roi.d.data.face.gaze_angle;
396
397 /* newly added */
398 // upscale by 2 to recover from demaen downscaling
399 mHalCamCtrl->mFace[idx].updown_dir = roi.d.data.face.updown_dir*2;
400 mHalCamCtrl->mFace[idx].leftright_dir = roi.d.data.face.leftright_dir*2;
401 mHalCamCtrl->mFace[idx].roll_dir = roi.d.data.face.roll_dir*2;
402
403 mHalCamCtrl->mFace[idx].leye_blink = roi.d.data.face.left_blink;
404 mHalCamCtrl->mFace[idx].reye_blink = roi.d.data.face.right_blink;
405 mHalCamCtrl->mFace[idx].left_right_gaze = roi.d.data.face.left_right_gaze;
406 mHalCamCtrl->mFace[idx].top_bottom_gaze = roi.d.data.face.top_bottom_gaze;
407 ALOGE("%s: Face(%d, %d, %d, %d), leftEye(%d, %d), rightEye(%d, %d), mouth(%d, %d), smile(%d, %d), face_recg(%d)", __func__,
408 mHalCamCtrl->mFace[idx].rect[0], mHalCamCtrl->mFace[idx].rect[1],
409 mHalCamCtrl->mFace[idx].rect[2], mHalCamCtrl->mFace[idx].rect[3],
410 mHalCamCtrl->mFace[idx].left_eye[0], mHalCamCtrl->mFace[idx].left_eye[1],
411 mHalCamCtrl->mFace[idx].right_eye[0], mHalCamCtrl->mFace[idx].right_eye[1],
412 mHalCamCtrl->mFace[idx].mouth[0], mHalCamCtrl->mFace[idx].mouth[1],
413 mHalCamCtrl->mFace[idx].smile_degree, mHalCamCtrl->mFace[idx].smile_score,
414 mHalCamCtrl->mFace[idx].face_recognised);
415 ALOGE("%s: gaze(%d, %d, %d), updown(%d), leftright(%d), roll(%d), blink(%d, %d, %d)", __func__,
416 mHalCamCtrl->mFace[idx].gaze_angle, mHalCamCtrl->mFace[idx].left_right_gaze,
417 mHalCamCtrl->mFace[idx].top_bottom_gaze, mHalCamCtrl->mFace[idx].updown_dir,
418 mHalCamCtrl->mFace[idx].leftright_dir, mHalCamCtrl->mFace[idx].roll_dir,
419 mHalCamCtrl->mFace[idx].blink_detected,
420 mHalCamCtrl->mFace[idx].leye_blink, mHalCamCtrl->mFace[idx].reye_blink);
421 #endif
422 mNumFDRcvd++;
423 mDisplayLock.unlock();
424
425 if (mNumFDRcvd == mHalCamCtrl->mMetadata.number_of_faces) {
426 mHalCamCtrl->mCallbackLock.lock();
427 camera_data_callback pcb = mHalCamCtrl->mDataCb;
428 mHalCamCtrl->mCallbackLock.unlock();
429
430 if (pcb && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA)){
431 ALOGV("%s: Face detection RIO callback with %d faces detected (score=%d)", __func__, mNumFDRcvd, mHalCamCtrl->mFace[idx].score);
432 pcb(CAMERA_MSG_PREVIEW_METADATA, data, 0, &mHalCamCtrl->mMetadata, mHalCamCtrl->mCallbackCookie);
433 }
434 }
435 #endif
436 }
437 break;
438 }
439 if(NULL != data) data->release(data);
440 }
441
initDisplayBuffers()442 status_t QCameraStream_preview::initDisplayBuffers()
443 {
444 status_t ret = NO_ERROR;
445 int width = 0; /* width of channel */
446 int height = 0; /* height of channel */
447 uint32_t frame_len = 0; /* frame planner length */
448 int buffer_num = 4, i; /* number of buffers for display */
449 const char *pmem_region;
450 uint8_t num_planes = 0;
451 uint32_t planes[VIDEO_MAX_PLANES];
452 void *vaddr = NULL;
453 cam_ctrl_dimension_t dim;
454
455 ALOGV("%s:BEGIN",__func__);
456 memset(&mHalCamCtrl->mMetadata, 0, sizeof(camera_frame_metadata_t));
457 mHalCamCtrl->mPreviewMemoryLock.lock();
458 memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory));
459 mHalCamCtrl->mPreviewMemoryLock.unlock();
460
461 /* get preview size, by qury mm_camera*/
462 memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
463
464 memset(&(this->mDisplayStreamBuf),0, sizeof(this->mDisplayStreamBuf));
465
466 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
467 if (MM_CAMERA_OK != ret) {
468 ALOGE("%s: error - can't get camera dimension!", __func__);
469 ALOGV("%s: X", __func__);
470 return BAD_VALUE;
471 }else {
472 width = dim.display_width,
473 height = dim.display_height;
474 }
475
476 ret = getBufferFromSurface();
477 if(ret != NO_ERROR) {
478 ALOGE("%s: cannot get memory from surface texture client, ret = %d", __func__, ret);
479 return ret;
480 }
481
482 /* set 4 buffers for display */
483 mHalCamCtrl->mPreviewMemoryLock.lock();
484 memset(&mDisplayStreamBuf, 0, sizeof(mDisplayStreamBuf));
485 this->mDisplayStreamBuf.num = mHalCamCtrl->mPreviewMemory.buffer_count;
486 this->myMode=myMode; /*Need to assign this in constructor after translating from mask*/
487 num_planes = dim.display_frame_offset.num_planes;
488 for(i =0; i< num_planes; i++) {
489 planes[i] = dim.display_frame_offset.mp[i].len;
490 }
491 this->mDisplayStreamBuf.frame_len = dim.display_frame_offset.frame_len;
492
493 memset(&mDisplayBuf, 0, sizeof(mDisplayBuf));
494 mDisplayBuf.preview.buf.mp = new mm_camera_mp_buf_t[mDisplayStreamBuf.num];
495 if (!mDisplayBuf.preview.buf.mp) {
496 ALOGE("%s Error allocating memory for mplanar struct ", __func__);
497 ret = NO_MEMORY;
498 goto error;
499 }
500 memset(mDisplayBuf.preview.buf.mp, 0,
501 mDisplayStreamBuf.num * sizeof(mm_camera_mp_buf_t));
502
503 /*allocate memory for the buffers*/
504 for(int i = 0; i < mDisplayStreamBuf.num; i++){
505 if (mHalCamCtrl->mPreviewMemory.private_buffer_handle[i] == NULL)
506 continue;
507 mDisplayStreamBuf.frame[i].fd = mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->fd;
508 mDisplayStreamBuf.frame[i].cbcr_off = planes[0];
509 mDisplayStreamBuf.frame[i].y_off = 0;
510 mDisplayStreamBuf.frame[i].path = OUTPUT_TYPE_P;
511 mHalCamCtrl->mPreviewMemory.addr_offset[i] =
512 mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->offset;
513 mDisplayStreamBuf.frame[i].buffer =
514 (long unsigned int)mHalCamCtrl->mPreviewMemory.camera_memory[i]->data;
515 mDisplayStreamBuf.frame[i].ion_alloc.len = mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size;
516 mDisplayStreamBuf.frame[i].ion_dev_fd = mHalCamCtrl->mPreviewMemory.main_ion_fd[i];
517 mDisplayStreamBuf.frame[i].fd_data = mHalCamCtrl->mPreviewMemory.ion_info_fd[i];
518
519 ALOGV("%s: idx = %d, fd = %d, size = %d, cbcr_offset = %d, y_offset = %d, "
520 "offset = %d, vaddr = 0x%x", __func__, i, mDisplayStreamBuf.frame[i].fd,
521 mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size,
522 mDisplayStreamBuf.frame[i].cbcr_off, mDisplayStreamBuf.frame[i].y_off,
523 mHalCamCtrl->mPreviewMemory.addr_offset[i],
524 (uint32_t)mDisplayStreamBuf.frame[i].buffer);
525
526 ret = mHalCamCtrl->sendMappingBuf(
527 MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW,
528 i,
529 mDisplayStreamBuf.frame[i].fd,
530 mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size,
531 mCameraId, CAM_SOCK_MSG_TYPE_FD_MAPPING);
532 if (NO_ERROR != ret) {
533 ALOGE("%s: sending mapping data Msg Failed", __func__);
534 goto error;
535 }
536
537 if(mHalCamCtrl->isZSLMode()) {
538 ret = mHalCamCtrl->sendMappingBuf(
539 MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL,
540 i,
541 mDisplayStreamBuf.frame[i].fd,
542 mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size,
543 mCameraId, CAM_SOCK_MSG_TYPE_FD_MAPPING);
544 if (NO_ERROR != ret) {
545 ALOGE("%s: Send socket msg to map Failed", __func__);
546 goto error;
547 }
548 }
549 mDisplayBuf.preview.buf.mp[i].frame = mDisplayStreamBuf.frame[i];
550 mDisplayBuf.preview.buf.mp[i].frame_offset = mHalCamCtrl->mPreviewMemory.addr_offset[i];
551 mDisplayBuf.preview.buf.mp[i].num_planes = num_planes;
552
553 /* Plane 0 needs to be set seperately. Set other planes
554 * in a loop. */
555 mDisplayBuf.preview.buf.mp[i].planes[0].length = planes[0];
556 mDisplayBuf.preview.buf.mp[i].planes[0].m.userptr = mDisplayStreamBuf.frame[i].fd;
557 mDisplayBuf.preview.buf.mp[i].planes[0].data_offset = 0;
558 mDisplayBuf.preview.buf.mp[i].planes[0].reserved[0] =
559 mDisplayBuf.preview.buf.mp[i].frame_offset;
560 for (int j = 1; j < num_planes; j++) {
561 mDisplayBuf.preview.buf.mp[i].planes[j].length = planes[j];
562 mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr =
563 mDisplayStreamBuf.frame[i].fd;
564 mDisplayBuf.preview.buf.mp[i].planes[j].data_offset = 0;
565 mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0] =
566 mDisplayBuf.preview.buf.mp[i].planes[j-1].reserved[0] +
567 mDisplayBuf.preview.buf.mp[i].planes[j-1].length;
568 }
569
570 if (mHalCamCtrl->mPreviewMemory.local_flag[i] == BUFFER_NOT_OWNED) {
571 mDisplayBuf.preview.no_enqueue_flag[i] = 1;
572 } else {
573 mDisplayBuf.preview.no_enqueue_flag[i] = 0;
574 }
575 for (int j = 0; j < num_planes; j++)
576 ALOGV("Planes: %d length: %d userptr: %lu offset: %d\n", j,
577 mDisplayBuf.preview.buf.mp[i].planes[j].length,
578 mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr,
579 mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0]);
580 }/*end of for loop*/
581
582 /* register the streaming buffers for the channel*/
583 mDisplayBuf.ch_type = MM_CAMERA_CH_PREVIEW;
584 mDisplayBuf.preview.num = mDisplayStreamBuf.num;
585 mHalCamCtrl->mPreviewMemoryLock.unlock();
586 ALOGV("%s:END",__func__);
587 return NO_ERROR;
588
589 error:
590 mHalCamCtrl->mPreviewMemoryLock.unlock();
591 putBufferToSurface();
592
593 ALOGV("%s: X", __func__);
594 return ret;
595 }
596
dumpFrameToFile(struct msm_frame * newFrame)597 void QCameraStream_preview::dumpFrameToFile(struct msm_frame* newFrame)
598 {
599 #if 0
600 int32_t enabled = 0;
601 int frm_num;
602 uint32_t skip_mode;
603 char value[PROPERTY_VALUE_MAX];
604 char buf[32];
605 int w, h;
606 static int count = 0;
607 cam_ctrl_dimension_t dim;
608 int file_fd;
609 int rc = 0;
610 int len;
611 unsigned long addr;
612 unsigned long * tmp = (unsigned long *)newFrame->buffer;
613 addr = *tmp;
614 status_t ret = cam_config_get_parm(mHalCamCtrl->mCameraId,
615 MM_CAMERA_PARM_DIMENSION, &dim);
616
617 w = dim.display_width;
618 h = dim.display_height;
619 len = (w * h)*3/2;
620 count++;
621 if(count < 100) {
622 snprintf(buf, sizeof(buf), "/data/mzhu%d.yuv", count);
623 file_fd = open(buf, O_RDWR | O_CREAT, 0777);
624
625 rc = write(file_fd, (const void *)addr, len);
626 ALOGV("%s: file='%s', vaddr_old=0x%x, addr_map = 0x%p, len = %d, rc = %d",
627 __func__, buf, (uint32_t)newFrame->buffer, (void *)addr, len, rc);
628 close(file_fd);
629 ALOGV("%s: dump %s, rc = %d, len = %d", __func__, buf, rc, len);
630 }
631 #endif
632 }
633
processPreviewFrameWithDisplay(mm_camera_ch_data_buf_t * frame)634 status_t QCameraStream_preview::processPreviewFrameWithDisplay(
635 mm_camera_ch_data_buf_t *frame)
636 {
637 ALOGV("%s",__func__);
638 int err = 0;
639 int msgType = 0;
640 int i;
641 camera_memory_t *data = NULL;
642 camera_frame_metadata_t *metadata = NULL;
643
644 Mutex::Autolock lock(mStopCallbackLock);
645 if(!mActive) {
646 ALOGV("Preview Stopped. Returning callback");
647 return NO_ERROR;
648 }
649
650 if(mHalCamCtrl==NULL) {
651 ALOGE("%s: X: HAL control object not set",__func__);
652 /*Call buf done*/
653 return BAD_VALUE;
654 }
655
656 if(mHalCamCtrl->mPauseFramedispatch) {
657 if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, frame)) {
658 ALOGE("BUF DONE FAILED for the recylce buffer");
659 }
660 return NO_ERROR;
661 }
662 mHalCamCtrl->mCallbackLock.lock();
663 camera_data_timestamp_callback rcb = mHalCamCtrl->mDataCbTimestamp;
664 void *rdata = mHalCamCtrl->mCallbackCookie;
665 mHalCamCtrl->mCallbackLock.unlock();
666 nsecs_t timeStamp = seconds_to_nanoseconds(frame->def.frame->ts.tv_sec) ;
667 timeStamp += frame->def.frame->ts.tv_nsec;
668
669 if(mFirstFrameRcvd == false) {
670 mm_camera_util_profile("HAL: First preview frame received");
671 mFirstFrameRcvd = true;
672 }
673
674 if (UNLIKELY(mHalCamCtrl->mDebugFps)) {
675 mHalCamCtrl->debugShowPreviewFPS();
676 }
677 //dumpFrameToFile(frame->def.frame);
678 mHalCamCtrl->dumpFrameToFile(frame->def.frame, HAL_DUMP_FRM_PREVIEW);
679
680 mHalCamCtrl->mPreviewMemoryLock.lock();
681
682 ALOGV("Enqueue buf handle %p, index %d\n",
683 mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx], frame->def.idx);
684 ALOGV("%s: camera call genlock_unlock", __FUNCTION__);
685
686 if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx]) {
687 ALOGV("%s: genlock_unlock_buffer hdl =%p", __FUNCTION__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]));
688 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t*)
689 (*mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]))) {
690 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
691 //mHalCamCtrl->mPreviewMemoryLock.unlock();
692 //return -EINVAL;
693 } else {
694 mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx] = BUFFER_UNLOCKED;
695 }
696 } else {
697 ALOGE("%s: buffer to be enqueued is not locked", __FUNCTION__);
698 mHalCamCtrl->mPreviewMemoryLock.unlock();
699 return -EINVAL;
700 }
701
702 #ifdef USE_ION
703 struct ion_flush_data cache_inv_data;
704 int ion_fd;
705 ion_fd = frame->def.frame->ion_dev_fd;
706 cache_inv_data.vaddr = (void *)frame->def.frame->buffer;
707 cache_inv_data.fd = frame->def.frame->fd;
708 cache_inv_data.handle = frame->def.frame->fd_data.handle;
709 cache_inv_data.length = frame->def.frame->ion_alloc.len;
710
711 if (mHalCamCtrl->cache_ops(ion_fd, &cache_inv_data,
712 ION_IOC_CLEAN_INV_CACHES) < 0)
713 ALOGE("%s: Cache clean for Preview buffer %p fd = %d failed", __func__,
714 cache_inv_data.vaddr, cache_inv_data.fd);
715 #endif
716
717 if(mHFRFrameSkip == 1)
718 {
719 const char *str = mHalCamCtrl->mParameters.get(
720 QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE);
721 if(str != NULL){
722 int is_hfr_off = 0;
723 mHFRFrameCnt++;
724 if(!strcmp(str, QCameraParameters::VIDEO_HFR_OFF)) {
725 is_hfr_off = 1;
726 err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow,
727 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
728 } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_2X)) {
729 mHFRFrameCnt %= 2;
730 } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_3X)) {
731 mHFRFrameCnt %= 3;
732 } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_4X)) {
733 mHFRFrameCnt %= 4;
734 }
735 if(mHFRFrameCnt == 0)
736 err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow,
737 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
738 else if(!is_hfr_off)
739 err = this->mPreviewWindow->cancel_buffer(this->mPreviewWindow,
740 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
741 } else
742 err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow,
743 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
744 } else {
745 err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow,
746 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
747 }
748 if(err != 0) {
749 ALOGE("%s: enqueue_buffer failed, err = %d", __func__, err);
750 } else {
751 ALOGV("%s: enqueue_buffer hdl=%p", __func__, *mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
752 mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx] = BUFFER_NOT_OWNED;
753 }
754 buffer_handle_t *buffer_handle = NULL;
755 int tmp_stride = 0;
756 err = this->mPreviewWindow->dequeue_buffer(this->mPreviewWindow,
757 &buffer_handle, &tmp_stride);
758 if (err == NO_ERROR && buffer_handle != NULL) {
759
760 for(i = 0; i < mHalCamCtrl->mPreviewMemory.buffer_count; i++) {
761 if(mHalCamCtrl->mPreviewMemory.buffer_handle[i] == buffer_handle) {
762 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_UNLOCKED;
763 ALOGV("%s: dequed buf hdl =%p, index = %d", __func__, *buffer_handle, i);
764 break;
765 }
766 }
767 if (i < mHalCamCtrl->mPreviewMemory.buffer_count ) {
768 err = this->mPreviewWindow->lock_buffer(this->mPreviewWindow, buffer_handle);
769 ALOGV("%s: camera call genlock_lock: hdl =%p", __FUNCTION__, *buffer_handle);
770 if (GENLOCK_FAILURE == genlock_lock_buffer((native_handle_t*)(*buffer_handle), GENLOCK_WRITE_LOCK,
771 GENLOCK_MAX_TIMEOUT)) {
772 ALOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__);
773 //mHalCamCtrl->mPreviewMemoryLock.unlock();
774 // return -EINVAL;
775 } else {
776 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_LOCKED;
777 mm_camera_ch_data_buf_t notify;
778 memset(¬ify, 0, sizeof(mm_camera_ch_data_buf_t));
779 notify.type = MM_CAMERA_CH_PREVIEW;
780 notify.def.idx = i;
781 notify.def.frame = &mDisplayStreamBuf.frame[i];
782 ALOGV("%s: queueing buffer idx is %d", __func__, i);
783 if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, ¬ify)) {
784 ALOGE("%s: BUF DONE FAILED");
785 }
786 }
787 }
788 } else
789 ALOGV("%s: error in dequeue_buffer, enqueue_buffer idx = %d, no free buffer now", __func__, frame->def.idx);
790
791 /* Save the last displayed frame. We'll be using it to fill the gap between
792 when preview stops and postview start during snapshot.*/
793 mLastQueuedFrame = &(mDisplayStreamBuf.frame[frame->def.idx]);
794 mHalCamCtrl->mPreviewMemoryLock.unlock();
795
796 mHalCamCtrl->mCallbackLock.lock();
797 camera_data_callback pcb = mHalCamCtrl->mDataCb;
798 mHalCamCtrl->mCallbackLock.unlock();
799 ALOGV("Message enabled = 0x%x", mHalCamCtrl->mMsgEnabled);
800
801 camera_memory_t *previewMem = NULL;
802
803 if (pcb != NULL) {
804 ALOGV("%s: mMsgEnabled =0x%x, preview format =%d", __func__,
805 mHalCamCtrl->mMsgEnabled, mHalCamCtrl->mPreviewFormat);
806 //Sending preview callback if corresponding Msgs are enabled
807 if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) {
808 ALOGV("%s: PCB callback enabled", __func__);
809 msgType |= CAMERA_MSG_PREVIEW_FRAME;
810 int previewBufSize;
811 /* The preview buffer size sent back in the callback should be (width*height*bytes_per_pixel)
812 * As all preview formats we support, use 12 bits per pixel, buffer size = previewWidth * previewHeight * 3/2.
813 * We need to put a check if some other formats are supported in future. (punits) */
814 if ((mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_NV21) || (mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_NV12) ||
815 (mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_YV12))
816 {
817 if (mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_YV12) {
818 previewBufSize = ((mHalCamCtrl->mPreviewWidth+15)/16) *16* mHalCamCtrl->mPreviewHeight +
819 ((mHalCamCtrl->mPreviewWidth/2+15)/16)*16* mHalCamCtrl->mPreviewHeight;
820 } else {
821 previewBufSize = mHalCamCtrl->mPreviewWidth * mHalCamCtrl->mPreviewHeight * 3/2;
822 }
823 if(previewBufSize != mHalCamCtrl->mPreviewMemory.private_buffer_handle[frame->def.idx]->size) {
824 previewMem = mHalCamCtrl->mGetMemory(mHalCamCtrl->mPreviewMemory.private_buffer_handle[frame->def.idx]->fd,
825 previewBufSize, 1, mHalCamCtrl->mCallbackCookie);
826 if (!previewMem || !previewMem->data) {
827 ALOGE("%s: mGetMemory failed.\n", __func__);
828 } else {
829 data = previewMem;
830 }
831 } else
832 data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx];
833 } else {
834 data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx];
835 ALOGE("Invalid preview format, buffer size in preview callback may be wrong.");
836 }
837 } else {
838 data = NULL;
839 }
840 if(msgType) {
841 mStopCallbackLock.unlock();
842 if(mActive)
843 pcb(msgType, data, 0, metadata, mHalCamCtrl->mCallbackCookie);
844 if (previewMem)
845 previewMem->release(previewMem);
846 mStopCallbackLock.lock();
847 }
848 ALOGV("end of cb");
849 } else {
850 ALOGV("%s PCB is not enabled", __func__);
851 }
852 if(rcb != NULL && mVFEOutputs == 1)
853 {
854 int flagwait = 1;
855 if(mHalCamCtrl->mStartRecording == true &&
856 ( mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME))
857 {
858 if (mHalCamCtrl->mStoreMetaDataInFrame)
859 {
860 if(mHalCamCtrl->mRecordingMemory.metadata_memory[frame->def.idx])
861 {
862 flagwait = 1;
863 mStopCallbackLock.unlock();
864 rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
865 mHalCamCtrl->mRecordingMemory.metadata_memory[frame->def.idx],
866 0, mHalCamCtrl->mCallbackCookie);
867 mStopCallbackLock.lock();
868 }else
869 flagwait = 0;
870 }
871 else
872 {
873 mStopCallbackLock.unlock();
874 rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
875 mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx],
876 0, mHalCamCtrl->mCallbackCookie);
877 mStopCallbackLock.lock();
878 }
879
880 if(flagwait){
881 Mutex::Autolock rLock(&mHalCamCtrl->mRecordFrameLock);
882 if (mHalCamCtrl->mReleasedRecordingFrame != true) {
883 mHalCamCtrl->mRecordWait.wait(mHalCamCtrl->mRecordFrameLock);
884 }
885 mHalCamCtrl->mReleasedRecordingFrame = false;
886 }
887 }
888 }
889 /* Save the last displayed frame. We'll be using it to fill the gap between
890 when preview stops and postview start during snapshot.*/
891 //mLastQueuedFrame = frame->def.frame;
892 /*
893 if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, frame))
894 {
895 ALOGE("BUF DONE FAILED");
896 return BAD_VALUE;
897 }
898 */
899 return NO_ERROR;
900 }
901
processPreviewFrame(mm_camera_ch_data_buf_t * frame)902 status_t QCameraStream_preview::processPreviewFrame (
903 mm_camera_ch_data_buf_t *frame)
904 {
905 return processPreviewFrameWithDisplay(frame);
906 }
907
908 // ---------------------------------------------------------------------------
909 // QCameraStream_preview
910 // ---------------------------------------------------------------------------
911
912 QCameraStream_preview::
QCameraStream_preview(int cameraId,camera_mode_t mode)913 QCameraStream_preview(int cameraId, camera_mode_t mode)
914 : QCameraStream(cameraId,mode),
915 mLastQueuedFrame(NULL),
916 mNumFDRcvd(0),
917 mFirstFrameRcvd(false)
918 {
919 mHalCamCtrl = NULL;
920 ALOGV("%s: E", __func__);
921 ALOGV("%s: X", __func__);
922 }
923 // ---------------------------------------------------------------------------
924 // QCameraStream_preview
925 // ---------------------------------------------------------------------------
926
~QCameraStream_preview()927 QCameraStream_preview::~QCameraStream_preview() {
928 ALOGV("%s: E", __func__);
929 if(mActive) {
930 stop();
931 }
932 if(mInit) {
933 release();
934 }
935 mInit = false;
936 mActive = false;
937 ALOGV("%s: X", __func__);
938
939 }
940 // ---------------------------------------------------------------------------
941 // QCameraStream_preview
942 // ---------------------------------------------------------------------------
943
init()944 status_t QCameraStream_preview::init() {
945
946 status_t ret = NO_ERROR;
947 ALOGV("%s: E", __func__);
948
949 ret = QCameraStream::initChannel (mCameraId, MM_CAMERA_CH_PREVIEW_MASK);
950 if (NO_ERROR!=ret) {
951 ALOGE("%s E: can't init native cammera preview ch\n",__func__);
952 return ret;
953 }
954
955 /* register a notify into the mmmm_camera_t object*/
956 (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW,
957 preview_notify_cb,
958 MM_CAMERA_REG_BUF_CB_INFINITE,
959 0,this);
960 ALOGV("Debug : %s : cam_evt_register_buf_notify",__func__);
961 buffer_handle_t *buffer_handle = NULL;
962 int tmp_stride = 0;
963 mInit = true;
964 return ret;
965 }
966 // ---------------------------------------------------------------------------
967 // QCameraStream_preview
968 // ---------------------------------------------------------------------------
969
start()970 status_t QCameraStream_preview::start()
971 {
972 ALOGV("%s: E", __func__);
973 status_t ret = NO_ERROR;
974 cam_format_t previewFmt;
975 Mutex::Autolock lock(mStopCallbackLock);
976
977 /* call start() in parent class to start the monitor thread*/
978 //QCameraStream::start ();
979 previewFmt = mHalCamCtrl->getPreviewFormat();
980 setFormat(MM_CAMERA_CH_PREVIEW_MASK, previewFmt);
981
982 if(NO_ERROR!=initDisplayBuffers()){
983 return BAD_VALUE;
984 }
985 ALOGV("Debug : %s : initDisplayBuffers",__func__);
986
987 ret = cam_config_prepare_buf(mCameraId, &mDisplayBuf);
988 ALOGV("Debug : %s : cam_config_prepare_buf",__func__);
989 if(ret != MM_CAMERA_OK) {
990 ALOGV("%s:reg preview buf err=%d\n", __func__, ret);
991 ret = BAD_VALUE;
992 goto error;
993 }else {
994 ret = NO_ERROR;
995 }
996
997 /* For preview, the OP_MODE we set is dependent upon whether we are
998 starting camera or camcorder. For snapshot, anyway we disable preview.
999 However, for ZSL we need to set OP_MODE to OP_MODE_ZSL and not
1000 OP_MODE_VIDEO. We'll set that for now in CamCtrl. So in case of
1001 ZSL we skip setting Mode here */
1002
1003 if (!(myMode & CAMERA_ZSL_MODE)) {
1004 ALOGV("Setting OP MODE to MM_CAMERA_OP_MODE_VIDEO");
1005 mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_VIDEO;
1006 ret = cam_config_set_parm (mCameraId, MM_CAMERA_PARM_OP_MODE,
1007 &op_mode);
1008 ALOGV("OP Mode Set");
1009
1010 if(MM_CAMERA_OK != ret) {
1011 ALOGE("%s: X :set mode MM_CAMERA_OP_MODE_VIDEO err=%d\n", __func__, ret);
1012 ret = BAD_VALUE;
1013 goto error;
1014 }
1015 }else {
1016 ALOGV("Setting OP MODE to MM_CAMERA_OP_MODE_ZSL");
1017 mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_ZSL;
1018 ret = cam_config_set_parm (mCameraId, MM_CAMERA_PARM_OP_MODE,
1019 &op_mode);
1020 if(MM_CAMERA_OK != ret) {
1021 ALOGE("%s: X :set mode MM_CAMERA_OP_MODE_ZSL err=%d\n", __func__, ret);
1022 ret = BAD_VALUE;
1023 goto error;
1024 }
1025 }
1026
1027 /* call mm_camera action start(...) */
1028 ALOGV("Starting Preview/Video Stream. ");
1029 mFirstFrameRcvd = false;
1030 ret = cam_ops_action(mCameraId, true, MM_CAMERA_OPS_PREVIEW, 0);
1031
1032 if (MM_CAMERA_OK != ret) {
1033 ALOGE ("%s: preview streaming start err=%d\n", __func__, ret);
1034 ret = BAD_VALUE;
1035 goto error;
1036 }
1037
1038 ALOGV("Debug : %s : Preview streaming Started",__func__);
1039 ret = NO_ERROR;
1040
1041 mActive = true;
1042 goto end;
1043
1044 error:
1045 putBufferToSurface();
1046 end:
1047 ALOGV("%s: X", __func__);
1048 return ret;
1049 }
1050
1051
1052 // ---------------------------------------------------------------------------
1053 // QCameraStream_preview
1054 // ---------------------------------------------------------------------------
stop()1055 void QCameraStream_preview::stop() {
1056 ALOGV("%s: E", __func__);
1057 int ret=MM_CAMERA_OK;
1058
1059 if(!mActive) {
1060 return;
1061 }
1062 Mutex::Autolock lock(mStopCallbackLock);
1063 mActive = false;
1064 /* unregister the notify fn from the mmmm_camera_t object*/
1065
1066 ALOGV("%s: Stop the thread \n", __func__);
1067 /* call stop() in parent class to stop the monitor thread*/
1068 ret = cam_ops_action(mCameraId, false, MM_CAMERA_OPS_PREVIEW, 0);
1069 if(MM_CAMERA_OK != ret) {
1070 ALOGE ("%s: camera preview stop err=%d\n", __func__, ret);
1071 }
1072 ret = cam_config_unprepare_buf(mCameraId, MM_CAMERA_CH_PREVIEW);
1073 if(ret != MM_CAMERA_OK) {
1074 ALOGE("%s:Unreg preview buf err=%d\n", __func__, ret);
1075 //ret = BAD_VALUE;
1076 }
1077
1078 /* In case of a clean stop, we need to clean all buffers*/
1079 ALOGV("Debug : %s : Buffer Unprepared",__func__);
1080 /*free camera_memory handles and return buffer back to surface*/
1081 putBufferToSurface();
1082
1083 ALOGV("%s: X", __func__);
1084
1085 }
1086 // ---------------------------------------------------------------------------
1087 // QCameraStream_preview
1088 // ---------------------------------------------------------------------------
release()1089 void QCameraStream_preview::release() {
1090
1091 ALOGV("%s : BEGIN",__func__);
1092 int ret=MM_CAMERA_OK,i;
1093
1094 if(!mInit)
1095 {
1096 ALOGE("%s : Stream not Initalized",__func__);
1097 return;
1098 }
1099
1100 if(mActive) {
1101 this->stop();
1102 }
1103
1104 ret= QCameraStream::deinitChannel(mCameraId, MM_CAMERA_CH_PREVIEW);
1105 ALOGV("Debug : %s : De init Channel",__func__);
1106 if(ret != MM_CAMERA_OK) {
1107 ALOGE("%s:Deinit preview channel failed=%d\n", __func__, ret);
1108 //ret = BAD_VALUE;
1109 }
1110
1111 (void)cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW,
1112 NULL,
1113 (mm_camera_register_buf_cb_type_t)NULL,
1114 NULL,
1115 NULL);
1116 mInit = false;
1117 ALOGV("%s: END", __func__);
1118
1119 }
1120
1121 QCameraStream*
createInstance(int cameraId,camera_mode_t mode)1122 QCameraStream_preview::createInstance(int cameraId,
1123 camera_mode_t mode)
1124 {
1125 QCameraStream* pme = new QCameraStream_preview(cameraId, mode);
1126 return pme;
1127 }
1128 // ---------------------------------------------------------------------------
1129 // QCameraStream_preview
1130 // ---------------------------------------------------------------------------
1131
deleteInstance(QCameraStream * p)1132 void QCameraStream_preview::deleteInstance(QCameraStream *p)
1133 {
1134 if (p){
1135 ALOGV("%s: BEGIN", __func__);
1136 p->release();
1137 delete p;
1138 p = NULL;
1139 ALOGV("%s: END", __func__);
1140 }
1141 }
1142
1143
1144 /* Temp helper function */
getLastQueuedFrame(void)1145 void *QCameraStream_preview::getLastQueuedFrame(void)
1146 {
1147 return mLastQueuedFrame;
1148 }
1149
1150 // ---------------------------------------------------------------------------
1151 // No code beyone this line
1152 // ---------------------------------------------------------------------------
1153 }; // namespace android
1154