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