• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 ** Copyright (c) 2011-2012 The Linux Foundation. All rights reserved.
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 **     http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 */
16 
17 /*#error uncomment this for compiler test!*/
18 
19 #define 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 
318 
getBufferNoDisplay()319 status_t  QCameraStream_preview::getBufferNoDisplay( )
320 {
321   int err = 0;
322   status_t ret = NO_ERROR;
323   int i, num_planes, frame_len, y_off, cbcr_off;
324   cam_ctrl_dimension_t dim;
325   uint32_t planes[VIDEO_MAX_PLANES];
326 
327   ALOGV("%s : E ", __FUNCTION__);
328 
329 
330   ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
331   if(ret != NO_ERROR) {
332       ALOGE("%s: display format %d is not supported", __func__, dim.prev_format);
333     goto end;
334   }
335   mHalCamCtrl->mPreviewMemoryLock.lock();
336   mHalCamCtrl->mNoDispPreviewMemory.buffer_count = kPreviewBufferCount;
337   if(mHalCamCtrl->isZSLMode()) {
338     if(mHalCamCtrl->getZSLQueueDepth() > kPreviewBufferCount - 3)
339       mHalCamCtrl->mNoDispPreviewMemory.buffer_count =
340       mHalCamCtrl->getZSLQueueDepth() + 3;
341   }
342 
343   num_planes = dim.display_frame_offset.num_planes;
344   for ( i = 0; i < num_planes; i++) {
345     planes[i] = dim.display_frame_offset.mp[i].len;
346   }
347 
348   frame_len = dim.picture_frame_offset.frame_len;
349   y_off = dim.picture_frame_offset.mp[0].offset;
350   cbcr_off = dim.picture_frame_offset.mp[1].offset;
351   ALOGV("%s: main image: rotation = %d, yoff = %d, cbcroff = %d, size = %d, width = %d, height = %d",
352        __func__, dim.rotation, y_off, cbcr_off, frame_len,
353        dim.display_width, dim.display_height);
354   if (mHalCamCtrl->initHeapMem(&mHalCamCtrl->mNoDispPreviewMemory,
355      mHalCamCtrl->mNoDispPreviewMemory.buffer_count,
356      frame_len, y_off, cbcr_off, MSM_PMEM_MAINIMG,
357      NULL,NULL, num_planes, planes) < 0) {
358               ret = NO_MEMORY;
359               goto end;
360   };
361 
362   memset(&mHalCamCtrl->mMetadata, 0, sizeof(mHalCamCtrl->mMetadata));
363   memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace));
364 
365   ALOGV(" %s : X ",__FUNCTION__);
366 end:
367   //mDisplayLock.unlock();
368   mHalCamCtrl->mPreviewMemoryLock.unlock();
369 
370   return NO_ERROR;
371 }
372 
freeBufferNoDisplay()373 status_t   QCameraStream_preview::freeBufferNoDisplay()
374 {
375   int err = 0;
376   status_t ret = NO_ERROR;
377 
378   ALOGV(" %s : E ", __FUNCTION__);
379 
380   //mDisplayLock.lock();
381   mHalCamCtrl->mPreviewMemoryLock.lock();
382   for (int cnt = 0; cnt < mHalCamCtrl->mNoDispPreviewMemory.buffer_count; cnt++) {
383       if (cnt < mHalCamCtrl->mNoDispPreviewMemory.buffer_count) {
384           if (NO_ERROR != mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW,
385                        cnt, mCameraId, CAM_SOCK_MSG_TYPE_FD_UNMAPPING)) {
386               ALOGE("%s: sending data Msg Failed", __func__);
387           }
388           if(mHalCamCtrl->isZSLMode()) {
389               if (NO_ERROR != mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL, cnt, mCameraId,
390                                                             CAM_SOCK_MSG_TYPE_FD_UNMAPPING)) {
391                   ALOGE("%s: Send socket msg to Unmap Failed", __func__);
392               }
393           }
394       }
395   }
396   mHalCamCtrl->releaseHeapMem(&mHalCamCtrl->mNoDispPreviewMemory);
397   memset(&mHalCamCtrl->mNoDispPreviewMemory, 0, sizeof(mHalCamCtrl->mNoDispPreviewMemory));
398   if (mDisplayBuf.preview.buf.mp != NULL) {
399       delete[] mDisplayBuf.preview.buf.mp;
400       mDisplayBuf.preview.buf.mp = NULL;
401   }
402 
403   mHalCamCtrl->mPreviewMemoryLock.unlock();
404   ALOGV(" %s : X ",__FUNCTION__);
405   return NO_ERROR;
406 }
407 
notifyROIEvent(fd_roi_t roi)408 void QCameraStream_preview::notifyROIEvent(fd_roi_t roi)
409 {
410     camera_memory_t *data = mHalCamCtrl->mGetMemory(-1, 1, 1, NULL);
411     switch (roi.type) {
412     case FD_ROI_TYPE_HEADER:
413         {
414             mDisplayLock.lock();
415             mNumFDRcvd = 0;
416             memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace));
417             mHalCamCtrl->mMetadata.faces = mHalCamCtrl->mFace;
418             mHalCamCtrl->mMetadata.number_of_faces = roi.d.hdr.num_face_detected;
419             if(mHalCamCtrl->mMetadata.number_of_faces > MAX_ROI)
420               mHalCamCtrl->mMetadata.number_of_faces = MAX_ROI;
421             mDisplayLock.unlock();
422 
423             if (mHalCamCtrl->mMetadata.number_of_faces == 0) {
424                 // Clear previous faces
425                 mHalCamCtrl->mCallbackLock.lock();
426                 camera_data_callback pcb = mHalCamCtrl->mDataCb;
427                 mHalCamCtrl->mCallbackLock.unlock();
428 
429                 if (pcb && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA)){
430                     ALOGV("%s: Face detection RIO callback", __func__);
431                     pcb(CAMERA_MSG_PREVIEW_METADATA, data, 0, &mHalCamCtrl->mMetadata, mHalCamCtrl->mCallbackCookie);
432                 }
433             }
434         }
435         break;
436     case FD_ROI_TYPE_DATA:
437         {
438         #if 1
439             mDisplayLock.lock();
440             int idx = roi.d.data.idx;
441             if (idx >= mHalCamCtrl->mMetadata.number_of_faces) {
442                 mDisplayLock.unlock();
443                 ALOGE("%s: idx %d out of boundary %d", __func__, idx, mHalCamCtrl->mMetadata.number_of_faces);
444                 break;
445             }
446 
447             mHalCamCtrl->mFace[idx].id = roi.d.data.face.id;
448             mHalCamCtrl->mFace[idx].score = roi.d.data.face.score;
449 
450             // top
451             mHalCamCtrl->mFace[idx].rect[0] =
452                roi.d.data.face.face_boundary.x*2000/mHalCamCtrl->mDimension.display_width - 1000;
453             //right
454             mHalCamCtrl->mFace[idx].rect[1] =
455                roi.d.data.face.face_boundary.y*2000/mHalCamCtrl->mDimension.display_height - 1000;
456             //bottom
457             mHalCamCtrl->mFace[idx].rect[2] =  mHalCamCtrl->mFace[idx].rect[0] +
458                roi.d.data.face.face_boundary.dx*2000/mHalCamCtrl->mDimension.display_width;
459             //left
460             mHalCamCtrl->mFace[idx].rect[3] = mHalCamCtrl->mFace[idx].rect[1] +
461                roi.d.data.face.face_boundary.dy*2000/mHalCamCtrl->mDimension.display_height;
462 
463             // Center of left eye
464             mHalCamCtrl->mFace[idx].left_eye[0] =
465               roi.d.data.face.left_eye_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000;
466             mHalCamCtrl->mFace[idx].left_eye[1] =
467               roi.d.data.face.left_eye_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000;
468 
469             // Center of right eye
470             mHalCamCtrl->mFace[idx].right_eye[0] =
471               roi.d.data.face.right_eye_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000;
472             mHalCamCtrl->mFace[idx].right_eye[1] =
473               roi.d.data.face.right_eye_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000;
474 #if 0
475             // Center of mouth
476             mHalCamCtrl->mFace[idx].mouth[0] =
477               roi.d.data.face.mouth_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000;
478             mHalCamCtrl->mFace[idx].mouth[1] =
479               roi.d.data.face.mouth_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000;
480 
481             mHalCamCtrl->mFace[idx].smile_degree = roi.d.data.face.smile_degree;
482             mHalCamCtrl->mFace[idx].smile_score = roi.d.data.face.smile_confidence;
483             mHalCamCtrl->mFace[idx].blink_detected = roi.d.data.face.blink_detected;
484             mHalCamCtrl->mFace[idx].face_recognised = roi.d.data.face.is_face_recognised;
485             mHalCamCtrl->mFace[idx].gaze_angle = roi.d.data.face.gaze_angle;
486 
487             /* newly added */
488             // upscale by 2 to recover from demaen downscaling
489             mHalCamCtrl->mFace[idx].updown_dir = roi.d.data.face.updown_dir*2;
490             mHalCamCtrl->mFace[idx].leftright_dir = roi.d.data.face.leftright_dir*2;
491             mHalCamCtrl->mFace[idx].roll_dir = roi.d.data.face.roll_dir*2;
492 
493             mHalCamCtrl->mFace[idx].leye_blink = roi.d.data.face.left_blink;
494             mHalCamCtrl->mFace[idx].reye_blink = roi.d.data.face.right_blink;
495             mHalCamCtrl->mFace[idx].left_right_gaze = roi.d.data.face.left_right_gaze;
496             mHalCamCtrl->mFace[idx].top_bottom_gaze = roi.d.data.face.top_bottom_gaze;
497             ALOGE("%s: Face(%d, %d, %d, %d), leftEye(%d, %d), rightEye(%d, %d), mouth(%d, %d), smile(%d, %d), face_recg(%d)", __func__,
498                mHalCamCtrl->mFace[idx].rect[0],  mHalCamCtrl->mFace[idx].rect[1],
499                mHalCamCtrl->mFace[idx].rect[2],  mHalCamCtrl->mFace[idx].rect[3],
500                mHalCamCtrl->mFace[idx].left_eye[0], mHalCamCtrl->mFace[idx].left_eye[1],
501                mHalCamCtrl->mFace[idx].right_eye[0], mHalCamCtrl->mFace[idx].right_eye[1],
502                mHalCamCtrl->mFace[idx].mouth[0], mHalCamCtrl->mFace[idx].mouth[1],
503                mHalCamCtrl->mFace[idx].smile_degree, mHalCamCtrl->mFace[idx].smile_score,
504                mHalCamCtrl->mFace[idx].face_recognised);
505             ALOGE("%s: gaze(%d, %d, %d), updown(%d), leftright(%d), roll(%d), blink(%d, %d, %d)", __func__,
506                mHalCamCtrl->mFace[idx].gaze_angle,  mHalCamCtrl->mFace[idx].left_right_gaze,
507                mHalCamCtrl->mFace[idx].top_bottom_gaze,  mHalCamCtrl->mFace[idx].updown_dir,
508                mHalCamCtrl->mFace[idx].leftright_dir, mHalCamCtrl->mFace[idx].roll_dir,
509                mHalCamCtrl->mFace[idx].blink_detected,
510                mHalCamCtrl->mFace[idx].leye_blink, mHalCamCtrl->mFace[idx].reye_blink);
511 #endif
512              mNumFDRcvd++;
513              mDisplayLock.unlock();
514 
515              if (mNumFDRcvd == mHalCamCtrl->mMetadata.number_of_faces) {
516                  mHalCamCtrl->mCallbackLock.lock();
517                  camera_data_callback pcb = mHalCamCtrl->mDataCb;
518                  mHalCamCtrl->mCallbackLock.unlock();
519 
520                  if (pcb && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA)){
521                      ALOGV("%s: Face detection RIO callback with %d faces detected (score=%d)", __func__, mNumFDRcvd, mHalCamCtrl->mFace[idx].score);
522                      pcb(CAMERA_MSG_PREVIEW_METADATA, data, 0, &mHalCamCtrl->mMetadata, mHalCamCtrl->mCallbackCookie);
523                  }
524              }
525         #endif
526         }
527         break;
528     }
529     if(NULL != data) data->release(data);
530 }
531 
initDisplayBuffers()532 status_t QCameraStream_preview::initDisplayBuffers()
533 {
534   status_t ret = NO_ERROR;
535   int width = 0;  /* width of channel  */
536   int height = 0; /* height of channel */
537   uint32_t frame_len = 0; /* frame planner length */
538   int buffer_num = 4, i; /* number of buffers for display */
539   const char *pmem_region;
540   uint8_t num_planes = 0;
541   uint32_t planes[VIDEO_MAX_PLANES];
542   void *vaddr = NULL;
543   cam_ctrl_dimension_t dim;
544 
545   ALOGV("%s:BEGIN",__func__);
546   memset(&mHalCamCtrl->mMetadata, 0, sizeof(camera_frame_metadata_t));
547   mHalCamCtrl->mPreviewMemoryLock.lock();
548   memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory));
549   mHalCamCtrl->mPreviewMemoryLock.unlock();
550   memset(&mNotifyBuffer, 0, sizeof(mNotifyBuffer));
551 
552 /* get preview size, by qury mm_camera*/
553   memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
554 
555   memset(&(this->mDisplayStreamBuf),0, sizeof(this->mDisplayStreamBuf));
556 
557   ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
558   if (MM_CAMERA_OK != ret) {
559     ALOGE("%s: error - can't get camera dimension!", __func__);
560     ALOGV("%s: X", __func__);
561     return BAD_VALUE;
562   }else {
563     width =  dim.display_width,
564     height = dim.display_height;
565   }
566 
567   ret = getBufferFromSurface();
568   if(ret != NO_ERROR) {
569     ALOGE("%s: cannot get memory from surface texture client, ret = %d", __func__, ret);
570     return ret;
571   }
572 
573   /* set 4 buffers for display */
574   mHalCamCtrl->mPreviewMemoryLock.lock();
575   memset(&mDisplayStreamBuf, 0, sizeof(mDisplayStreamBuf));
576   this->mDisplayStreamBuf.num = mHalCamCtrl->mPreviewMemory.buffer_count;
577   this->myMode=myMode; /*Need to assign this in constructor after translating from mask*/
578   num_planes = dim.display_frame_offset.num_planes;
579   for(i =0; i< num_planes; i++) {
580      planes[i] = dim.display_frame_offset.mp[i].len;
581   }
582   this->mDisplayStreamBuf.frame_len = dim.display_frame_offset.frame_len;
583 
584   memset(&mDisplayBuf, 0, sizeof(mDisplayBuf));
585   mDisplayBuf.preview.buf.mp = new mm_camera_mp_buf_t[mDisplayStreamBuf.num];
586   if (!mDisplayBuf.preview.buf.mp) {
587     ALOGE("%s Error allocating memory for mplanar struct ", __func__);
588     ret = NO_MEMORY;
589     goto error;
590   }
591   memset(mDisplayBuf.preview.buf.mp, 0,
592     mDisplayStreamBuf.num * sizeof(mm_camera_mp_buf_t));
593 
594   /*allocate memory for the buffers*/
595   for(int i = 0; i < mDisplayStreamBuf.num; i++){
596 	  if (mHalCamCtrl->mPreviewMemory.private_buffer_handle[i] == NULL)
597 		  continue;
598       mDisplayStreamBuf.frame[i].fd = mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->fd;
599       mDisplayStreamBuf.frame[i].cbcr_off = planes[0];
600       mDisplayStreamBuf.frame[i].y_off = 0;
601       mDisplayStreamBuf.frame[i].path = OUTPUT_TYPE_P;
602 	  mHalCamCtrl->mPreviewMemory.addr_offset[i] =
603 	      mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->offset;
604       mDisplayStreamBuf.frame[i].buffer =
605           (long unsigned int)mHalCamCtrl->mPreviewMemory.camera_memory[i]->data;
606       mDisplayStreamBuf.frame[i].ion_alloc.len = mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size;
607       mDisplayStreamBuf.frame[i].ion_dev_fd = mHalCamCtrl->mPreviewMemory.main_ion_fd[i];
608       mDisplayStreamBuf.frame[i].fd_data = mHalCamCtrl->mPreviewMemory.ion_info_fd[i];
609 
610     ALOGV("%s: idx = %d, fd = %d, size = %d, cbcr_offset = %d, y_offset = %d, "
611       "offset = %d, vaddr = 0x%x", __func__, i, mDisplayStreamBuf.frame[i].fd,
612       mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size,
613       mDisplayStreamBuf.frame[i].cbcr_off, mDisplayStreamBuf.frame[i].y_off,
614       mHalCamCtrl->mPreviewMemory.addr_offset[i],
615       (uint32_t)mDisplayStreamBuf.frame[i].buffer);
616 
617     ret = mHalCamCtrl->sendMappingBuf(
618                         MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW,
619                         i,
620                         mDisplayStreamBuf.frame[i].fd,
621                         mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size,
622                         mCameraId, CAM_SOCK_MSG_TYPE_FD_MAPPING);
623     if (NO_ERROR != ret) {
624       ALOGE("%s: sending mapping data Msg Failed", __func__);
625       goto error;
626     }
627 
628     if(mHalCamCtrl->isZSLMode()) {
629          ret = mHalCamCtrl->sendMappingBuf(
630                         MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL,
631                         i,
632                         mDisplayStreamBuf.frame[i].fd,
633                         mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size,
634                         mCameraId, CAM_SOCK_MSG_TYPE_FD_MAPPING);
635         if (NO_ERROR != ret) {
636           ALOGE("%s: Send socket msg to map Failed", __func__);
637           goto error;
638         }
639     }
640     mDisplayBuf.preview.buf.mp[i].frame = mDisplayStreamBuf.frame[i];
641     mDisplayBuf.preview.buf.mp[i].frame_offset = mHalCamCtrl->mPreviewMemory.addr_offset[i];
642     mDisplayBuf.preview.buf.mp[i].num_planes = num_planes;
643 
644     /* Plane 0 needs to be set seperately. Set other planes
645      * in a loop. */
646     mDisplayBuf.preview.buf.mp[i].planes[0].length = planes[0];
647     mDisplayBuf.preview.buf.mp[i].planes[0].m.userptr = mDisplayStreamBuf.frame[i].fd;
648     mDisplayBuf.preview.buf.mp[i].planes[0].data_offset = 0;
649     mDisplayBuf.preview.buf.mp[i].planes[0].reserved[0] =
650       mDisplayBuf.preview.buf.mp[i].frame_offset;
651     for (int j = 1; j < num_planes; j++) {
652       mDisplayBuf.preview.buf.mp[i].planes[j].length = planes[j];
653       mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr =
654         mDisplayStreamBuf.frame[i].fd;
655       mDisplayBuf.preview.buf.mp[i].planes[j].data_offset = 0;
656       mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0] =
657         mDisplayBuf.preview.buf.mp[i].planes[j-1].reserved[0] +
658         mDisplayBuf.preview.buf.mp[i].planes[j-1].length;
659     }
660 
661     for (int j = 0; j < num_planes; j++)
662       ALOGV("Planes: %d length: %d userptr: %lu offset: %d\n", j,
663         mDisplayBuf.preview.buf.mp[i].planes[j].length,
664         mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr,
665         mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0]);
666   }/*end of for loop*/
667 
668  /* register the streaming buffers for the channel*/
669   mDisplayBuf.ch_type = MM_CAMERA_CH_PREVIEW;
670   mDisplayBuf.preview.num = mDisplayStreamBuf.num;
671   mHalCamCtrl->mPreviewMemoryLock.unlock();
672   ALOGV("%s:END",__func__);
673   return NO_ERROR;
674 
675 error:
676     mHalCamCtrl->mPreviewMemoryLock.unlock();
677     putBufferToSurface();
678 
679     ALOGV("%s: X", __func__);
680     return ret;
681 }
682 
initPreviewOnlyBuffers()683 status_t QCameraStream_preview::initPreviewOnlyBuffers()
684 {
685   status_t ret = NO_ERROR;
686   int width = 0;  /* width of channel  */
687   int height = 0; /* height of channel */
688   uint32_t frame_len = 0; /* frame planner length */
689   int buffer_num = 4; /* number of buffers for display */
690   const char *pmem_region;
691   uint8_t num_planes = 0;
692   uint32_t planes[VIDEO_MAX_PLANES];
693 
694   cam_ctrl_dimension_t dim;
695 
696   ALOGV("%s:BEGIN",__func__);
697   memset(&mHalCamCtrl->mMetadata, 0, sizeof(camera_frame_metadata_t));
698   mHalCamCtrl->mPreviewMemoryLock.lock();
699   memset(&mHalCamCtrl->mNoDispPreviewMemory, 0, sizeof(mHalCamCtrl->mNoDispPreviewMemory));
700   mHalCamCtrl->mPreviewMemoryLock.unlock();
701   memset(&mNotifyBuffer, 0, sizeof(mNotifyBuffer));
702 
703 /* get preview size, by qury mm_camera*/
704   memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
705   ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
706   if (MM_CAMERA_OK != ret) {
707     ALOGE("%s: error - can't get camera dimension!", __func__);
708     ALOGV("%s: X", __func__);
709     return BAD_VALUE;
710   }else {
711     width =  dim.display_width;
712     height = dim.display_height;
713   }
714 
715   ret = getBufferNoDisplay( );
716   if(ret != NO_ERROR) {
717     ALOGE("%s: cannot get memory from surface texture client, ret = %d", __func__, ret);
718     return ret;
719   }
720 
721   /* set 4 buffers for display */
722   memset(&mDisplayStreamBuf, 0, sizeof(mDisplayStreamBuf));
723   mHalCamCtrl->mPreviewMemoryLock.lock();
724   this->mDisplayStreamBuf.num = mHalCamCtrl->mNoDispPreviewMemory.buffer_count;
725   this->myMode=myMode; /*Need to assign this in constructor after translating from mask*/
726   num_planes = dim.display_frame_offset.num_planes;
727   for (int i = 0; i < num_planes; i++) {
728     planes[i] = dim.display_frame_offset.mp[i].len;
729   }
730   this->mDisplayStreamBuf.frame_len = dim.display_frame_offset.frame_len;
731 
732   memset(&mDisplayBuf, 0, sizeof(mDisplayBuf));
733   mDisplayBuf.preview.buf.mp = new mm_camera_mp_buf_t[mDisplayStreamBuf.num];
734   if (!mDisplayBuf.preview.buf.mp) {
735     ALOGE("%s Error allocating memory for mplanar struct ", __func__);
736   }
737   memset(mDisplayBuf.preview.buf.mp, 0,
738     mDisplayStreamBuf.num * sizeof(mm_camera_mp_buf_t));
739 
740   /*allocate memory for the buffers*/
741   void *vaddr = NULL;
742   for(int i = 0; i < mDisplayStreamBuf.num; i++){
743 	  if (mHalCamCtrl->mNoDispPreviewMemory.camera_memory[i] == NULL)
744 		  continue;
745       mDisplayStreamBuf.frame[i].fd = mHalCamCtrl->mNoDispPreviewMemory.fd[i];
746       mDisplayStreamBuf.frame[i].cbcr_off = planes[0];
747       mDisplayStreamBuf.frame[i].y_off = 0;
748       mDisplayStreamBuf.frame[i].path = OUTPUT_TYPE_P;
749       mDisplayStreamBuf.frame[i].buffer =
750           (long unsigned int)mHalCamCtrl->mNoDispPreviewMemory.camera_memory[i]->data;
751       mDisplayStreamBuf.frame[i].ion_dev_fd = mHalCamCtrl->mNoDispPreviewMemory.main_ion_fd[i];
752       mDisplayStreamBuf.frame[i].fd_data = mHalCamCtrl->mNoDispPreviewMemory.ion_info_fd[i];
753 
754     ALOGV("%s: idx = %d, fd = %d, size = %d, cbcr_offset = %d, y_offset = %d, "
755       "vaddr = 0x%x", __func__, i, mDisplayStreamBuf.frame[i].fd,
756       frame_len,
757       mDisplayStreamBuf.frame[i].cbcr_off, mDisplayStreamBuf.frame[i].y_off,
758       (uint32_t)mDisplayStreamBuf.frame[i].buffer);
759 
760     if (NO_ERROR != mHalCamCtrl->sendMappingBuf(
761                         MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW,
762                         i,
763                         mDisplayStreamBuf.frame[i].fd,
764                         mHalCamCtrl->mNoDispPreviewMemory.size,
765                         mCameraId, CAM_SOCK_MSG_TYPE_FD_MAPPING)) {
766       ALOGE("%s: sending mapping data Msg Failed", __func__);
767     }
768 
769     if(mHalCamCtrl->isZSLMode()) {
770         if (NO_ERROR != mHalCamCtrl->sendMappingBuf(
771                     MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL,
772                     i,
773                     mDisplayStreamBuf.frame[i].fd,
774                     mHalCamCtrl->mNoDispPreviewMemory.size,
775                     mCameraId, CAM_SOCK_MSG_TYPE_FD_MAPPING)) {
776             ALOGE("%s: sending mapping data Msg Failed", __func__);
777         }
778     }
779     mDisplayBuf.preview.buf.mp[i].frame = mDisplayStreamBuf.frame[i];
780     mDisplayBuf.preview.buf.mp[i].frame_offset = mDisplayStreamBuf.frame[i].y_off;
781     mDisplayBuf.preview.buf.mp[i].num_planes = num_planes;
782 
783     /* Plane 0 needs to be set seperately. Set other planes
784      * in a loop. */
785     mDisplayBuf.preview.buf.mp[i].planes[0].length = planes[0];
786     mDisplayBuf.preview.buf.mp[i].planes[0].m.userptr = mDisplayStreamBuf.frame[i].fd;
787     mDisplayBuf.preview.buf.mp[i].planes[0].data_offset = 0;
788     mDisplayBuf.preview.buf.mp[i].planes[0].reserved[0] =
789       mDisplayBuf.preview.buf.mp[i].frame_offset;
790     for (int j = 1; j < num_planes; j++) {
791       mDisplayBuf.preview.buf.mp[i].planes[j].length = planes[j];
792       mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr =
793         mDisplayStreamBuf.frame[i].fd;
794       mDisplayBuf.preview.buf.mp[i].planes[j].data_offset = 0;
795       mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0] =
796         mDisplayBuf.preview.buf.mp[i].planes[j-1].reserved[0] +
797         mDisplayBuf.preview.buf.mp[i].planes[j-1].length;
798     }
799 
800     for (int j = 0; j < num_planes; j++)
801       ALOGV("Planes: %d length: %d userptr: %lu offset: %d\n", j,
802         mDisplayBuf.preview.buf.mp[i].planes[j].length,
803         mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr,
804         mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0]);
805   }/*end of for loop*/
806 
807  /* register the streaming buffers for the channel*/
808   mDisplayBuf.ch_type = MM_CAMERA_CH_PREVIEW;
809   mDisplayBuf.preview.num = mDisplayStreamBuf.num;
810   mHalCamCtrl->mPreviewMemoryLock.unlock();
811   ALOGV("%s:END",__func__);
812   return NO_ERROR;
813 
814 end:
815   if (MM_CAMERA_OK == ret ) {
816     ALOGV("%s: X - NO_ERROR ", __func__);
817     return NO_ERROR;
818   }
819 
820     ALOGV("%s: out of memory clean up", __func__);
821   /* release the allocated memory */
822 
823   ALOGV("%s: X - BAD_VALUE ", __func__);
824   return BAD_VALUE;
825 }
826 
827 
dumpFrameToFile(struct msm_frame * newFrame)828 void QCameraStream_preview::dumpFrameToFile(struct msm_frame* newFrame)
829 {
830 #if 0
831   int32_t enabled = 0;
832   int frm_num;
833   uint32_t  skip_mode;
834   char value[PROPERTY_VALUE_MAX];
835   char buf[32];
836   int w, h;
837   static int count = 0;
838   cam_ctrl_dimension_t dim;
839   int file_fd;
840   int rc = 0;
841   int len;
842   unsigned long addr;
843   unsigned long * tmp = (unsigned long *)newFrame->buffer;
844   addr = *tmp;
845   status_t ret = cam_config_get_parm(mHalCamCtrl->mCameraId,
846                  MM_CAMERA_PARM_DIMENSION, &dim);
847 
848   w = dim.display_width;
849   h = dim.display_height;
850   len = (w * h)*3/2;
851   count++;
852   if(count < 100) {
853     snprintf(buf, sizeof(buf), "/data/mzhu%d.yuv", count);
854     file_fd = open(buf, O_RDWR | O_CREAT, 0777);
855 
856     rc = write(file_fd, (const void *)addr, len);
857     ALOGV("%s: file='%s', vaddr_old=0x%x, addr_map = 0x%p, len = %d, rc = %d",
858           __func__, buf, (uint32_t)newFrame->buffer, (void *)addr, len, rc);
859     close(file_fd);
860     ALOGV("%s: dump %s, rc = %d, len = %d", __func__, buf, rc, len);
861   }
862 #endif
863 }
864 
processPreviewFrameWithDisplay(mm_camera_ch_data_buf_t * frame)865 status_t QCameraStream_preview::processPreviewFrameWithDisplay(
866   mm_camera_ch_data_buf_t *frame)
867 {
868   ALOGV("%s",__func__);
869   int err = 0;
870   int msgType = 0;
871   int i;
872   camera_memory_t *data = NULL;
873   camera_frame_metadata_t *metadata = NULL;
874 
875   Mutex::Autolock lock(mStopCallbackLock);
876   if(!mActive) {
877     ALOGV("Preview Stopped. Returning callback");
878     return NO_ERROR;
879   }
880 
881   if(mHalCamCtrl==NULL) {
882     ALOGE("%s: X: HAL control object not set",__func__);
883     /*Call buf done*/
884     return BAD_VALUE;
885   }
886 
887   if(mHalCamCtrl->mPauseFramedispatch) {
888       if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, frame)) {
889             ALOGE("BUF DONE FAILED for the recylce buffer");
890       }
891       return NO_ERROR;
892   }
893   mHalCamCtrl->mCallbackLock.lock();
894   camera_data_timestamp_callback rcb = mHalCamCtrl->mDataCbTimestamp;
895   void *rdata = mHalCamCtrl->mCallbackCookie;
896   mHalCamCtrl->mCallbackLock.unlock();
897   nsecs_t timeStamp = seconds_to_nanoseconds(frame->def.frame->ts.tv_sec) ;
898   timeStamp += frame->def.frame->ts.tv_nsec;
899 
900   if(mFirstFrameRcvd == false) {
901   mm_camera_util_profile("HAL: First preview frame received");
902   mFirstFrameRcvd = true;
903   }
904 
905   if (UNLIKELY(mHalCamCtrl->mDebugFps)) {
906       mHalCamCtrl->debugShowPreviewFPS();
907   }
908   //dumpFrameToFile(frame->def.frame);
909   mHalCamCtrl->dumpFrameToFile(frame->def.frame, HAL_DUMP_FRM_PREVIEW);
910 
911   mHalCamCtrl->mPreviewMemoryLock.lock();
912   mNotifyBuffer[frame->def.idx] = *frame;
913 
914   ALOGV("Enqueue buf handle %p\n",
915   mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
916   ALOGV("%s: camera call genlock_unlock", __FUNCTION__);
917 
918     if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx]) {
919       ALOGV("%s: genlock_unlock_buffer hdl =%p", __FUNCTION__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]));
920         if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t*)
921                 (*mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]))) {
922             ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
923             //mHalCamCtrl->mPreviewMemoryLock.unlock();
924             //return -EINVAL;
925         } else {
926             mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx] = BUFFER_UNLOCKED;
927         }
928     } else {
929         ALOGE("%s: buffer to be enqueued is not locked", __FUNCTION__);
930 	    mHalCamCtrl->mPreviewMemoryLock.unlock();
931         return -EINVAL;
932     }
933 
934 #ifdef USE_ION
935   struct ion_flush_data cache_inv_data;
936   int ion_fd;
937   ion_fd = frame->def.frame->ion_dev_fd;
938   cache_inv_data.vaddr = (void *)frame->def.frame->buffer;
939   cache_inv_data.fd = frame->def.frame->fd;
940   cache_inv_data.handle = frame->def.frame->fd_data.handle;
941   cache_inv_data.length = frame->def.frame->ion_alloc.len;
942 
943   if (mHalCamCtrl->cache_ops(ion_fd, &cache_inv_data,
944                                 ION_IOC_CLEAN_INV_CACHES) < 0)
945     ALOGE("%s: Cache clean for Preview buffer %p fd = %d failed", __func__,
946       cache_inv_data.vaddr, cache_inv_data.fd);
947 #endif
948 
949   if(mHFRFrameSkip == 1)
950   {
951       const char *str = mHalCamCtrl->mParameters.get(
952                           QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE);
953       if(str != NULL){
954       int is_hfr_off = 0;
955       mHFRFrameCnt++;
956       if(!strcmp(str, QCameraParameters::VIDEO_HFR_OFF)) {
957           is_hfr_off = 1;
958           err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow,
959             (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
960       } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_2X)) {
961           mHFRFrameCnt %= 2;
962       } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_3X)) {
963           mHFRFrameCnt %= 3;
964       } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_4X)) {
965           mHFRFrameCnt %= 4;
966       }
967       if(mHFRFrameCnt == 0)
968           err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow,
969             (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
970       else if(!is_hfr_off)
971           err = this->mPreviewWindow->cancel_buffer(this->mPreviewWindow,
972             (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
973       } else
974           err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow,
975             (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
976   } else {
977       err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow,
978           (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
979   }
980   if(err != 0) {
981     ALOGE("%s: enqueue_buffer failed, err = %d", __func__, err);
982   } else {
983    ALOGV("%s: enqueue_buffer hdl=%p", __func__, *mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
984     mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx] = BUFFER_NOT_OWNED;
985   }
986   buffer_handle_t *buffer_handle = NULL;
987   int tmp_stride = 0;
988   err = this->mPreviewWindow->dequeue_buffer(this->mPreviewWindow,
989               &buffer_handle, &tmp_stride);
990   if (err == NO_ERROR && buffer_handle != NULL) {
991 
992     ALOGV("%s: dequed buf hdl =%p", __func__, *buffer_handle);
993     for(i = 0; i < mHalCamCtrl->mPreviewMemory.buffer_count; i++) {
994         if(mHalCamCtrl->mPreviewMemory.buffer_handle[i] == buffer_handle) {
995           mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_UNLOCKED;
996           break;
997         }
998     }
999      if (i < mHalCamCtrl->mPreviewMemory.buffer_count ) {
1000       err = this->mPreviewWindow->lock_buffer(this->mPreviewWindow, buffer_handle);
1001       ALOGV("%s: camera call genlock_lock: hdl =%p", __FUNCTION__, *buffer_handle);
1002       if (GENLOCK_FAILURE == genlock_lock_buffer((native_handle_t*)(*buffer_handle), GENLOCK_WRITE_LOCK,
1003                                                  GENLOCK_MAX_TIMEOUT)) {
1004             ALOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__);
1005 	    //mHalCamCtrl->mPreviewMemoryLock.unlock();
1006            // return -EINVAL;
1007       } else  {
1008         mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_LOCKED;
1009 
1010         if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, &mNotifyBuffer[i])) {
1011             ALOGE("BUF DONE FAILED");
1012         }
1013       }
1014      }
1015   } else
1016       ALOGV("%s: error in dequeue_buffer, enqueue_buffer idx = %d, no free buffer now", __func__, frame->def.idx);
1017 
1018   /* Save the last displayed frame. We'll be using it to fill the gap between
1019      when preview stops and postview start during snapshot.*/
1020   mLastQueuedFrame = &(mDisplayStreamBuf.frame[frame->def.idx]);
1021   mHalCamCtrl->mPreviewMemoryLock.unlock();
1022 
1023   mHalCamCtrl->mCallbackLock.lock();
1024   camera_data_callback pcb = mHalCamCtrl->mDataCb;
1025   mHalCamCtrl->mCallbackLock.unlock();
1026   ALOGV("Message enabled = 0x%x", mHalCamCtrl->mMsgEnabled);
1027 
1028   camera_memory_t *previewMem = NULL;
1029 
1030   if (pcb != NULL) {
1031        ALOGV("%s: mMsgEnabled =0x%x, preview format =%d", __func__,
1032             mHalCamCtrl->mMsgEnabled, mHalCamCtrl->mPreviewFormat);
1033       //Sending preview callback if corresponding Msgs are enabled
1034       if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) {
1035           ALOGV("%s: PCB callback enabled", __func__);
1036           msgType |=  CAMERA_MSG_PREVIEW_FRAME;
1037           int previewBufSize;
1038           /* The preview buffer size sent back in the callback should be (width*height*bytes_per_pixel)
1039            * As all preview formats we support, use 12 bits per pixel, buffer size = previewWidth * previewHeight * 3/2.
1040            * We need to put a check if some other formats are supported in future. (punits) */
1041           if ((mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_NV21) || (mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_NV12) ||
1042                     (mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_YV12))
1043           {
1044               if (mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_YV12) {
1045                 previewBufSize = ((mHalCamCtrl->mPreviewWidth+15)/16) *16* mHalCamCtrl->mPreviewHeight +
1046                   ((mHalCamCtrl->mPreviewWidth/2+15)/16)*16* mHalCamCtrl->mPreviewHeight;
1047               } else {
1048                 previewBufSize = mHalCamCtrl->mPreviewWidth * mHalCamCtrl->mPreviewHeight * 3/2;
1049               }
1050               if(previewBufSize != mHalCamCtrl->mPreviewMemory.private_buffer_handle[frame->def.idx]->size) {
1051                   previewMem = mHalCamCtrl->mGetMemory(mHalCamCtrl->mPreviewMemory.private_buffer_handle[frame->def.idx]->fd,
1052                   previewBufSize, 1, mHalCamCtrl->mCallbackCookie);
1053                   if (!previewMem || !previewMem->data) {
1054                       ALOGE("%s: mGetMemory failed.\n", __func__);
1055                   } else {
1056                       data = previewMem;
1057                   }
1058               } else
1059                     data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx];
1060           } else {
1061                 data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx];
1062                 ALOGE("Invalid preview format, buffer size in preview callback may be wrong.");
1063           }
1064       } else {
1065           data = NULL;
1066       }
1067       if(msgType) {
1068           mStopCallbackLock.unlock();
1069           if(mActive)
1070             pcb(msgType, data, 0, metadata, mHalCamCtrl->mCallbackCookie);
1071           if (previewMem)
1072               previewMem->release(previewMem);
1073           mStopCallbackLock.lock();
1074       }
1075 	  ALOGV("end of cb");
1076   } else {
1077     ALOGV("%s PCB is not enabled", __func__);
1078   }
1079   if(rcb != NULL && mVFEOutputs == 1)
1080   {
1081       int flagwait = 1;
1082       if(mHalCamCtrl->mStartRecording == true &&
1083               ( mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME))
1084       {
1085         if (mHalCamCtrl->mStoreMetaDataInFrame)
1086         {
1087           if(mHalCamCtrl->mRecordingMemory.metadata_memory[frame->def.idx])
1088           {
1089               flagwait = 1;
1090               mStopCallbackLock.unlock();
1091               rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
1092                       mHalCamCtrl->mRecordingMemory.metadata_memory[frame->def.idx],
1093                       0, mHalCamCtrl->mCallbackCookie);
1094               mStopCallbackLock.lock();
1095           }else
1096               flagwait = 0;
1097       }
1098       else
1099       {
1100               mStopCallbackLock.unlock();
1101               rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
1102                       mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx],
1103                       0, mHalCamCtrl->mCallbackCookie);
1104               mStopCallbackLock.lock();
1105       }
1106 
1107       if(flagwait){
1108           Mutex::Autolock rLock(&mHalCamCtrl->mRecordFrameLock);
1109           if (mHalCamCtrl->mReleasedRecordingFrame != true) {
1110               mHalCamCtrl->mRecordWait.wait(mHalCamCtrl->mRecordFrameLock);
1111           }
1112           mHalCamCtrl->mReleasedRecordingFrame = false;
1113       }
1114       }
1115   }
1116   /* Save the last displayed frame. We'll be using it to fill the gap between
1117      when preview stops and postview start during snapshot.*/
1118   //mLastQueuedFrame = frame->def.frame;
1119 /*
1120   if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, frame))
1121   {
1122       ALOGE("BUF DONE FAILED");
1123       return BAD_VALUE;
1124   }
1125 */
1126   return NO_ERROR;
1127 }
1128 
1129 
processPreviewFrameWithOutDisplay(mm_camera_ch_data_buf_t * frame)1130 status_t QCameraStream_preview::processPreviewFrameWithOutDisplay(
1131   mm_camera_ch_data_buf_t *frame)
1132 {
1133   ALOGV("%s",__func__);
1134   int err = 0;
1135   int msgType = 0;
1136   int i;
1137   camera_memory_t *data = NULL;
1138   camera_frame_metadata_t *metadata = NULL;
1139 
1140   Mutex::Autolock lock(mStopCallbackLock);
1141   if(!mActive) {
1142     ALOGV("Preview Stopped. Returning callback");
1143     return NO_ERROR;
1144   }
1145   if(mHalCamCtrl==NULL) {
1146     ALOGE("%s: X: HAL control object not set",__func__);
1147     /*Call buf done*/
1148     return BAD_VALUE;
1149   }
1150 
1151   if (UNLIKELY(mHalCamCtrl->mDebugFps)) {
1152       mHalCamCtrl->debugShowPreviewFPS();
1153   }
1154   //dumpFrameToFile(frame->def.frame);
1155   mHalCamCtrl->dumpFrameToFile(frame->def.frame, HAL_DUMP_FRM_PREVIEW);
1156 
1157   mHalCamCtrl->mPreviewMemoryLock.lock();
1158   mNotifyBuffer[frame->def.idx] = *frame;
1159 
1160   /* Save the last displayed frame. We'll be using it to fill the gap between
1161      when preview stops and postview start during snapshot.*/
1162   mLastQueuedFrame = &(mDisplayStreamBuf.frame[frame->def.idx]);
1163   mHalCamCtrl->mPreviewMemoryLock.unlock();
1164 
1165   mHalCamCtrl->mCallbackLock.lock();
1166   camera_data_callback pcb = mHalCamCtrl->mDataCb;
1167   mHalCamCtrl->mCallbackLock.unlock();
1168   ALOGV("Message enabled = 0x%x", mHalCamCtrl->mMsgEnabled);
1169 
1170   camera_memory_t *previewMem = NULL;
1171   int previewWidth, previewHeight;
1172   mHalCamCtrl->mParameters.getPreviewSize(&previewWidth, &previewHeight);
1173 
1174 #ifdef USE_ION
1175   struct ion_flush_data cache_inv_data;
1176   int ion_fd;
1177   ion_fd = frame->def.frame->ion_dev_fd;
1178   cache_inv_data.vaddr = (void *)frame->def.frame->buffer;
1179   cache_inv_data.fd = frame->def.frame->fd;
1180   cache_inv_data.handle = frame->def.frame->fd_data.handle;
1181   cache_inv_data.length = frame->def.frame->ion_alloc.len;
1182 
1183   if (mHalCamCtrl->cache_ops(ion_fd, &cache_inv_data,
1184                                 ION_IOC_CLEAN_INV_CACHES) < 0)
1185     ALOGE("%s: Cache clean for Preview buffer %p fd = %d failed", __func__,
1186       cache_inv_data.vaddr, cache_inv_data.fd);
1187 #endif
1188 
1189   if (pcb != NULL) {
1190       //Sending preview callback if corresponding Msgs are enabled
1191       if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) {
1192           msgType |=  CAMERA_MSG_PREVIEW_FRAME;
1193           int previewBufSize;
1194           /* For CTS : Forcing preview memory buffer lenth to be
1195              'previewWidth * previewHeight * 3/2'.
1196               Needed when gralloc allocated extra memory.*/
1197           //Can add this check for other formats as well.
1198           if( mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_NV21) {
1199               previewBufSize = previewWidth * previewHeight * 3/2;
1200               if(previewBufSize != mHalCamCtrl->mPreviewMemory.private_buffer_handle[frame->def.idx]->size) {
1201                   previewMem = mHalCamCtrl->mGetMemory(mHalCamCtrl->mPreviewMemory.private_buffer_handle[frame->def.idx]->fd,
1202                   previewBufSize, 1, mHalCamCtrl->mCallbackCookie);
1203                   if (!previewMem || !previewMem->data) {
1204                       ALOGE("%s: mGetMemory failed.\n", __func__);
1205                   } else {
1206                       data = previewMem;
1207                   }
1208               } else
1209                     data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx];//mPreviewHeap->mBuffers[frame->def.idx];
1210           } else
1211                 data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx];//mPreviewHeap->mBuffers[frame->def.idx];
1212       } else {
1213           data = NULL;
1214       }
1215 
1216       if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA){
1217           msgType  |= CAMERA_MSG_PREVIEW_METADATA;
1218           metadata = &mHalCamCtrl->mMetadata;
1219       } else {
1220           metadata = NULL;
1221       }
1222       if(msgType) {
1223           mStopCallbackLock.unlock();
1224           if(mActive)
1225             pcb(msgType, data, 0, metadata, mHalCamCtrl->mCallbackCookie);
1226           if (previewMem)
1227               previewMem->release(previewMem);
1228           mStopCallbackLock.lock();
1229       }
1230 
1231       if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, &mNotifyBuffer[frame->def.idx])) {
1232           ALOGE("BUF DONE FAILED");
1233       }
1234 
1235       ALOGV("end of cb");
1236   }
1237 
1238   return NO_ERROR;
1239 }
1240 
processPreviewFrame(mm_camera_ch_data_buf_t * frame)1241 status_t QCameraStream_preview::processPreviewFrame (
1242   mm_camera_ch_data_buf_t *frame)
1243 {
1244   if (mHalCamCtrl->isNoDisplayMode()) {
1245     return processPreviewFrameWithOutDisplay(frame);
1246   } else {
1247     return processPreviewFrameWithDisplay(frame);
1248   }
1249 }
1250 
1251 // ---------------------------------------------------------------------------
1252 // QCameraStream_preview
1253 // ---------------------------------------------------------------------------
1254 
1255 QCameraStream_preview::
QCameraStream_preview(int cameraId,camera_mode_t mode)1256 QCameraStream_preview(int cameraId, camera_mode_t mode)
1257   : QCameraStream(cameraId,mode),
1258     mLastQueuedFrame(NULL),
1259     mNumFDRcvd(0),
1260     mFirstFrameRcvd(false)
1261   {
1262     mHalCamCtrl = NULL;
1263     ALOGV("%s: E", __func__);
1264     ALOGV("%s: X", __func__);
1265   }
1266 // ---------------------------------------------------------------------------
1267 // QCameraStream_preview
1268 // ---------------------------------------------------------------------------
1269 
~QCameraStream_preview()1270 QCameraStream_preview::~QCameraStream_preview() {
1271     ALOGV("%s: E", __func__);
1272 	if(mActive) {
1273 		stop();
1274 	}
1275 	if(mInit) {
1276 		release();
1277 	}
1278 	mInit = false;
1279 	mActive = false;
1280     ALOGV("%s: X", __func__);
1281 
1282 }
1283 // ---------------------------------------------------------------------------
1284 // QCameraStream_preview
1285 // ---------------------------------------------------------------------------
1286 
init()1287 status_t QCameraStream_preview::init() {
1288 
1289   status_t ret = NO_ERROR;
1290   ALOGV("%s: E", __func__);
1291 
1292   ret = QCameraStream::initChannel (mCameraId, MM_CAMERA_CH_PREVIEW_MASK);
1293   if (NO_ERROR!=ret) {
1294     ALOGE("%s E: can't init native cammera preview ch\n",__func__);
1295     return ret;
1296   }
1297 
1298   /* register a notify into the mmmm_camera_t object*/
1299   (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW,
1300                                      preview_notify_cb,
1301                                      MM_CAMERA_REG_BUF_CB_INFINITE,
1302                                      0,this);
1303   ALOGV("Debug : %s : cam_evt_register_buf_notify",__func__);
1304   buffer_handle_t *buffer_handle = NULL;
1305   int tmp_stride = 0;
1306   mInit = true;
1307   return ret;
1308 }
1309 // ---------------------------------------------------------------------------
1310 // QCameraStream_preview
1311 // ---------------------------------------------------------------------------
1312 
start()1313 status_t QCameraStream_preview::start()
1314 {
1315     ALOGV("%s: E", __func__);
1316     status_t ret = NO_ERROR;
1317     cam_format_t previewFmt;
1318     Mutex::Autolock lock(mStopCallbackLock);
1319 
1320     /* call start() in parent class to start the monitor thread*/
1321     //QCameraStream::start ();
1322     previewFmt = mHalCamCtrl->getPreviewFormat();
1323     setFormat(MM_CAMERA_CH_PREVIEW_MASK, previewFmt);
1324 
1325     if (mHalCamCtrl->isNoDisplayMode()) {
1326         if(NO_ERROR!=initPreviewOnlyBuffers()){
1327             return BAD_VALUE;
1328         }
1329     } else {
1330         if(NO_ERROR!=initDisplayBuffers()){
1331             return BAD_VALUE;
1332         }
1333     }
1334     ALOGV("Debug : %s : initDisplayBuffers",__func__);
1335 
1336     ret = cam_config_prepare_buf(mCameraId, &mDisplayBuf);
1337     ALOGV("Debug : %s : cam_config_prepare_buf",__func__);
1338     if(ret != MM_CAMERA_OK) {
1339         ALOGV("%s:reg preview buf err=%d\n", __func__, ret);
1340         ret = BAD_VALUE;
1341         goto error;
1342     }else {
1343         ret = NO_ERROR;
1344     }
1345 
1346 	/* For preview, the OP_MODE we set is dependent upon whether we are
1347        starting camera or camcorder. For snapshot, anyway we disable preview.
1348        However, for ZSL we need to set OP_MODE to OP_MODE_ZSL and not
1349        OP_MODE_VIDEO. We'll set that for now in CamCtrl. So in case of
1350        ZSL we skip setting Mode here */
1351 
1352     if (!(myMode & CAMERA_ZSL_MODE)) {
1353         ALOGV("Setting OP MODE to MM_CAMERA_OP_MODE_VIDEO");
1354         mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_VIDEO;
1355         ret = cam_config_set_parm (mCameraId, MM_CAMERA_PARM_OP_MODE,
1356                                         &op_mode);
1357         ALOGV("OP Mode Set");
1358 
1359         if(MM_CAMERA_OK != ret) {
1360           ALOGE("%s: X :set mode MM_CAMERA_OP_MODE_VIDEO err=%d\n", __func__, ret);
1361           ret = BAD_VALUE;
1362           goto error;
1363         }
1364     }else {
1365         ALOGV("Setting OP MODE to MM_CAMERA_OP_MODE_ZSL");
1366         mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_ZSL;
1367         ret = cam_config_set_parm (mCameraId, MM_CAMERA_PARM_OP_MODE,
1368                                         &op_mode);
1369         if(MM_CAMERA_OK != ret) {
1370           ALOGE("%s: X :set mode MM_CAMERA_OP_MODE_ZSL err=%d\n", __func__, ret);
1371           ret = BAD_VALUE;
1372           goto error;
1373         }
1374      }
1375 
1376     /* call mm_camera action start(...)  */
1377     ALOGV("Starting Preview/Video Stream. ");
1378     mFirstFrameRcvd = false;
1379     ret = cam_ops_action(mCameraId, true, MM_CAMERA_OPS_PREVIEW, 0);
1380 
1381     if (MM_CAMERA_OK != ret) {
1382       ALOGE ("%s: preview streaming start err=%d\n", __func__, ret);
1383       ret = BAD_VALUE;
1384       goto error;
1385     }
1386 
1387     ALOGV("Debug : %s : Preview streaming Started",__func__);
1388     ret = NO_ERROR;
1389 
1390     mActive =  true;
1391     goto end;
1392 
1393 error:
1394     putBufferToSurface();
1395 end:
1396     ALOGV("%s: X", __func__);
1397     return ret;
1398   }
1399 
1400 
1401 // ---------------------------------------------------------------------------
1402 // QCameraStream_preview
1403 // ---------------------------------------------------------------------------
stop()1404   void QCameraStream_preview::stop() {
1405     ALOGV("%s: E", __func__);
1406     int ret=MM_CAMERA_OK;
1407 
1408     if(!mActive) {
1409       return;
1410     }
1411     Mutex::Autolock lock(mStopCallbackLock);
1412     mActive =  false;
1413     /* unregister the notify fn from the mmmm_camera_t object*/
1414 
1415     ALOGV("%s: Stop the thread \n", __func__);
1416     /* call stop() in parent class to stop the monitor thread*/
1417     ret = cam_ops_action(mCameraId, false, MM_CAMERA_OPS_PREVIEW, 0);
1418     if(MM_CAMERA_OK != ret) {
1419       ALOGE ("%s: camera preview stop err=%d\n", __func__, ret);
1420     }
1421     ret = cam_config_unprepare_buf(mCameraId, MM_CAMERA_CH_PREVIEW);
1422     if(ret != MM_CAMERA_OK) {
1423       ALOGE("%s:Unreg preview buf err=%d\n", __func__, ret);
1424       //ret = BAD_VALUE;
1425     }
1426 
1427     /* In case of a clean stop, we need to clean all buffers*/
1428     ALOGV("Debug : %s : Buffer Unprepared",__func__);
1429     /*free camera_memory handles and return buffer back to surface*/
1430     if (! mHalCamCtrl->isNoDisplayMode() ) {
1431       putBufferToSurface();
1432     } else {
1433       freeBufferNoDisplay( );
1434     }
1435 
1436     ALOGV("%s: X", __func__);
1437 
1438   }
1439 // ---------------------------------------------------------------------------
1440 // QCameraStream_preview
1441 // ---------------------------------------------------------------------------
release()1442   void QCameraStream_preview::release() {
1443 
1444     ALOGV("%s : BEGIN",__func__);
1445     int ret=MM_CAMERA_OK,i;
1446 
1447     if(!mInit)
1448     {
1449       ALOGE("%s : Stream not Initalized",__func__);
1450       return;
1451     }
1452 
1453     if(mActive) {
1454       this->stop();
1455     }
1456 
1457     ret= QCameraStream::deinitChannel(mCameraId, MM_CAMERA_CH_PREVIEW);
1458     ALOGV("Debug : %s : De init Channel",__func__);
1459     if(ret != MM_CAMERA_OK) {
1460       ALOGE("%s:Deinit preview channel failed=%d\n", __func__, ret);
1461       //ret = BAD_VALUE;
1462     }
1463 
1464     (void)cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW,
1465                                       NULL,
1466                                       (mm_camera_register_buf_cb_type_t)NULL,
1467                                       NULL,
1468                                       NULL);
1469     mInit = false;
1470     ALOGV("%s: END", __func__);
1471 
1472   }
1473 
1474 QCameraStream*
createInstance(int cameraId,camera_mode_t mode)1475 QCameraStream_preview::createInstance(int cameraId,
1476                                       camera_mode_t mode)
1477 {
1478   QCameraStream* pme = new QCameraStream_preview(cameraId, mode);
1479   return pme;
1480 }
1481 // ---------------------------------------------------------------------------
1482 // QCameraStream_preview
1483 // ---------------------------------------------------------------------------
1484 
deleteInstance(QCameraStream * p)1485 void QCameraStream_preview::deleteInstance(QCameraStream *p)
1486 {
1487   if (p){
1488     ALOGV("%s: BEGIN", __func__);
1489     p->release();
1490     delete p;
1491     p = NULL;
1492     ALOGV("%s: END", __func__);
1493   }
1494 }
1495 
1496 
1497 /* Temp helper function */
getLastQueuedFrame(void)1498 void *QCameraStream_preview::getLastQueuedFrame(void)
1499 {
1500     return mLastQueuedFrame;
1501 }
1502 
1503 // ---------------------------------------------------------------------------
1504 // No code beyone this line
1505 // ---------------------------------------------------------------------------
1506 }; // namespace android
1507