Home | History | Annotate | Download | only in camera
      1 /*
      2 ** Copyright (c) 2012 The Linux Foundation. All rights reserved.
      3 **
      4 ** Licensed under the Apache License, Version 2.0 (the "License");
      5 ** you may not use this file except in compliance with the License.
      6 ** You may obtain a copy of the License at
      7 **
      8 **     http://www.apache.org/licenses/LICENSE-2.0
      9 **
     10 ** Unless required by applicable law or agreed to in writing, software
     11 ** distributed under the License is distributed on an "AS IS" BASIS,
     12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 ** See the License for the specific language governing permissions and
     14 ** limitations under the License.
     15 */
     16 
     17 /*#error uncomment this for compiler test!*/
     18 
     19 #define ALOG_NDEBUG 0
     20 #define ALOG_NIDEBUG 0
     21 #define LOG_TAG "QCameraHWI_Preview"
     22 #include <utils/Log.h>
     23 #include <utils/threads.h>
     24 #include <fcntl.h>
     25 #include <sys/mman.h>
     26 
     27 #include "QCameraHAL.h"
     28 #include "QCameraHWI.h"
     29 #include <gralloc_priv.h>
     30 #include <genlock.h>
     31 
     32 #define UNLIKELY(exp) __builtin_expect(!!(exp), 0)
     33 
     34 /* QCameraHWI_Preview class implementation goes here*/
     35 /* following code implement the preview mode's image capture & display logic of this class*/
     36 
     37 namespace android {
     38 
     39 // ---------------------------------------------------------------------------
     40 // Preview Callback
     41 // ---------------------------------------------------------------------------
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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::
    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 
    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 
    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 
    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 // ---------------------------------------------------------------------------
    792   void QCameraStream_preview::stop() {
    793     ALOGE("%s: E", __func__);
    794     int ret=MM_CAMERA_OK;
    795 
    796     if(!mActive) {
    797       return;
    798     }
    799     mActive =  false;
    800     Mutex::Autolock lock(mStopCallbackLock);
    801     /* unregister the notify fn from the mmmm_camera_t object*/
    802 
    803     /* call stop() in parent class to stop the monitor thread*/
    804     ret = cam_ops_action(mCameraId, FALSE, MM_CAMERA_OPS_PREVIEW, 0);
    805     if(MM_CAMERA_OK != ret) {
    806       ALOGE ("%s: camera preview stop err=%d\n", __func__, ret);
    807     }
    808     ALOGE("Debug : %s : Preview streaming Stopped",__func__);
    809     ret = cam_config_unprepare_buf(mCameraId, MM_CAMERA_CH_PREVIEW);
    810     if(ret != MM_CAMERA_OK) {
    811       ALOGE("%s:Unreg preview buf err=%d\n", __func__, ret);
    812       //ret = BAD_VALUE;
    813     }
    814 
    815     ALOGE("Debug : %s : Buffer Unprepared",__func__);
    816     if (mDisplayBuf.preview.buf.mp != NULL) {
    817         delete[] mDisplayBuf.preview.buf.mp;
    818     }
    819 	/*free camera_memory handles and return buffer back to surface*/
    820     putBufferToSurface();
    821 
    822     ALOGE("%s: X", __func__);
    823 
    824   }
    825 // ---------------------------------------------------------------------------
    826 // QCameraStream_preview
    827 // ---------------------------------------------------------------------------
    828   void QCameraStream_preview::release() {
    829 
    830     ALOGE("%s : BEGIN",__func__);
    831     int ret=MM_CAMERA_OK,i;
    832 
    833     if(!mInit)
    834     {
    835       ALOGE("%s : Stream not Initalized",__func__);
    836       return;
    837     }
    838 
    839     if(mActive) {
    840       this->stop();
    841     }
    842 
    843     ret= QCameraStream::deinitChannel(mCameraId, MM_CAMERA_CH_PREVIEW);
    844     ALOGE("Debug : %s : De init Channel",__func__);
    845     if(ret != MM_CAMERA_OK) {
    846       ALOGE("%s:Deinit preview channel failed=%d\n", __func__, ret);
    847       //ret = BAD_VALUE;
    848     }
    849 
    850     (void)cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW,
    851                                       NULL,
    852 					(mm_camera_register_buf_cb_type_t)NULL,
    853 					NULL,
    854 					NULL);
    855 	mInit = false;
    856     ALOGE("%s: END", __func__);
    857 
    858   }
    859 
    860 QCameraStream*
    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 
    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 */
    884 void *QCameraStream_preview::getLastQueuedFrame(void)
    885 {
    886     return mLastQueuedFrame;
    887 }
    888 
    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