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(&notify, 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, &notify)) {
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