Home | History | Annotate | Download | only in src
      1 /*
      2 ** Copyright (c) 2012 The Linux Foundation. All rights reserved.
      3 **
      4 ** Not a Contribution, Apache license notifications and license are retained
      5 ** for attribution purposes only.
      6 **
      7 ** Licensed under the Apache License, Version 2.0 (the "License");
      8 ** you may not use this file except in compliance with the License.
      9 ** You may obtain a copy of the License at
     10 **
     11 **     http://www.apache.org/licenses/LICENSE-2.0
     12 **
     13 ** Unless required by applicable law or agreed to in writing, software
     14 ** distributed under the License is distributed on an "AS IS" BASIS,
     15 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16 ** See the License for the specific language governing permissions and
     17 ** limitations under the License.
     18 */
     19 
     20 /*#error uncomment this for compiler test!*/
     21 
     22 #define LOG_TAG "QCameraHWI_Preview"
     23 #include <utils/Log.h>
     24 #include <utils/threads.h>
     25 #include <fcntl.h>
     26 #include <sys/mman.h>
     27 #include "QCameraHAL.h"
     28 #include "QCameraHWI.h"
     29 #include <genlock.h>
     30 #include <gralloc_priv.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 status_t QCameraStream_preview::getBufferFromSurface() {
     40     int err = 0;
     41     status_t ret = NO_ERROR;
     42     int gralloc_usage;
     43     struct ion_fd_data ion_info_fd;
     44     preview_stream_ops_t *previewWindow = mHalCamCtrl->mPreviewWindow;
     45 
     46     ALOGI(" %s : E ", __FUNCTION__);
     47 
     48     if( previewWindow == NULL) {
     49         ALOGE("%s: PreviewWindow = NULL", __func__);
     50             return INVALID_OPERATION;
     51     }
     52 
     53     mHalCamCtrl->mPreviewMemoryLock.lock();
     54     mHalCamCtrl->mPreviewMemory.buffer_count = mNumBuffers;
     55     err = previewWindow->set_buffer_count(previewWindow, mHalCamCtrl->mPreviewMemory.buffer_count );
     56     if (err != 0) {
     57          ALOGE("set_buffer_count failed: %s (%d)",
     58                     strerror(-err), -err);
     59          ret = UNKNOWN_ERROR;
     60          goto end;
     61     }
     62 
     63     err = previewWindow->set_buffers_geometry(previewWindow, mWidth, mHeight,
     64                                               mHalCamCtrl->getPreviewFormatInfo().Hal_format);
     65     if (err != 0) {
     66          ALOGE("set_buffers_geometry failed: %s (%d)",
     67                     strerror(-err), -err);
     68          ret = UNKNOWN_ERROR;
     69          goto end;
     70     }
     71 
     72     ret = p_mm_ops->ops->get_parm(mCameraHandle, MM_CAMERA_PARM_VFE_OUTPUT_ENABLE, &mVFEOutputs);
     73     if(ret != MM_CAMERA_OK) {
     74         ALOGE("get parm MM_CAMERA_PARM_VFE_OUTPUT_ENABLE  failed");
     75         ret = BAD_VALUE;
     76         goto end;
     77     }
     78 
     79     //as software encoder is used to encode 720p, to enhance the performance
     80     //cashed pmem is used here
     81     if(mVFEOutputs == 1)
     82         gralloc_usage = CAMERA_GRALLOC_HEAP_ID | CAMERA_GRALLOC_FALLBACK_HEAP_ID;
     83     else
     84         gralloc_usage = CAMERA_GRALLOC_HEAP_ID | CAMERA_GRALLOC_FALLBACK_HEAP_ID |
     85                     CAMERA_GRALLOC_CACHING_ID;
     86     err = previewWindow->set_usage(previewWindow, gralloc_usage);
     87     if(err != 0) {
     88     /* set_usage error out */
     89         ALOGE("%s: set_usage rc = %d", __func__, err);
     90         ret = UNKNOWN_ERROR;
     91         goto end;
     92     }
     93     ret = p_mm_ops->ops->get_parm(mCameraHandle, MM_CAMERA_PARM_HFR_FRAME_SKIP, &mHFRFrameSkip);
     94     if(ret != MM_CAMERA_OK) {
     95         ALOGE("get parm MM_CAMERA_PARM_HFR_FRAME_SKIP  failed");
     96         ret = BAD_VALUE;
     97         goto end;
     98     }
     99 	for (int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) {
    100 		int stride;
    101 		err = previewWindow->dequeue_buffer(previewWindow,
    102 										&mHalCamCtrl->mPreviewMemory.buffer_handle[cnt],
    103 										&mHalCamCtrl->mPreviewMemory.stride[cnt]);
    104 		if(!err) {
    105             ALOGV("%s: dequeue buf hdl =%p", __func__, *mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
    106             err = previewWindow->lock_buffer(previewWindow,
    107                                        mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
    108             // lock the buffer using genlock
    109             ALOGV("%s: camera call genlock_lock, hdl=%p",
    110                           __FUNCTION__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]));
    111             if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t *)(*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]),
    112                                                       GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
    113                 ALOGE("%s: genlock_lock_buffer(WRITE) failed", __func__);
    114                 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_UNLOCKED;
    115             } else {
    116                 ALOGV("%s: genlock_lock_buffer hdl =%p", __func__, *mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
    117                 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_LOCKED;
    118             }
    119 		} else {
    120             mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_NOT_OWNED;
    121             ALOGE("%s: dequeue_buffer idx = %d err = %d", __func__, cnt, err);
    122         }
    123 
    124 		ALOGV("%s: dequeue buf: %p\n", __func__, mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
    125 
    126 		if(err != 0) {
    127             ALOGE("%s: dequeue_buffer failed: %s (%d)", __func__,
    128                     strerror(-err), -err);
    129             ret = UNKNOWN_ERROR;
    130 			for(int i = 0; i < cnt; i++) {
    131                 if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[i]) {
    132                       ALOGD("%s: camera call genlock_unlock", __func__);
    133                      if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *)
    134                                                   (*(mHalCamCtrl->mPreviewMemory.buffer_handle[i])))) {
    135                         ALOGE("%s: genlock_unlock_buffer failed: hdl =%p", __func__, (*(mHalCamCtrl->mPreviewMemory.buffer_handle[i])) );
    136                      } else {
    137                        mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_UNLOCKED;
    138                      }
    139                 }
    140                 if( mHalCamCtrl->mPreviewMemory.local_flag[i] != BUFFER_NOT_OWNED) {
    141                   err = previewWindow->cancel_buffer(previewWindow,
    142                                           mHalCamCtrl->mPreviewMemory.buffer_handle[i]);
    143                 }
    144                 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_NOT_OWNED;
    145                 ALOGD("%s: cancel_buffer: hdl =%p", __func__,  (*mHalCamCtrl->mPreviewMemory.buffer_handle[i]));
    146 				mHalCamCtrl->mPreviewMemory.buffer_handle[i] = NULL;
    147 			}
    148             memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory));
    149 			goto end;
    150 		}
    151 
    152 		mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt] =
    153 		    (struct private_handle_t *)(*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
    154 #ifdef USE_ION
    155         mHalCamCtrl->mPreviewMemory.mem_info[cnt].main_ion_fd = open("/dev/ion", O_RDONLY);
    156         if (mHalCamCtrl->mPreviewMemory.mem_info[cnt].main_ion_fd < 0) {
    157             ALOGE("%s: failed: could not open ion device\n", __func__);
    158         } else {
    159             memset(&ion_info_fd, 0, sizeof(ion_info_fd));
    160             ion_info_fd.fd = mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd;
    161             if (ioctl(mHalCamCtrl->mPreviewMemory.mem_info[cnt].main_ion_fd,
    162                       ION_IOC_IMPORT, &ion_info_fd) < 0) {
    163                 ALOGE("ION import failed\n");
    164             }
    165         }
    166 #endif
    167 		mHalCamCtrl->mPreviewMemory.camera_memory[cnt] =
    168 		    mHalCamCtrl->mGetMemory(mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd,
    169                                     mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size,
    170                                     1,
    171                                     (void *)this);
    172 		ALOGD("%s: idx = %d, fd = %d, size = %d, offset = %d", __func__,
    173               cnt, mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd,
    174               mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size,
    175               mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->offset);
    176 
    177         mHalCamCtrl->mPreviewMemory.mem_info[cnt].fd =
    178             mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd;
    179         mHalCamCtrl->mPreviewMemory.mem_info[cnt].size =
    180             mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size;
    181         mHalCamCtrl->mPreviewMemory.mem_info[cnt].handle = ion_info_fd.handle;
    182     }
    183 
    184     memset(&mHalCamCtrl->mMetadata, 0, sizeof(mHalCamCtrl->mMetadata));
    185     memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace));
    186 
    187 end:
    188     mHalCamCtrl->mPreviewMemoryLock.unlock();
    189 
    190     ALOGI(" %s : X ",__func__);
    191     return ret;
    192 }
    193 
    194 status_t QCameraStream_preview::putBufferToSurface() {
    195     int err = 0;
    196     status_t ret = NO_ERROR;
    197 
    198     ALOGI(" %s : E ", __FUNCTION__);
    199 
    200     mHalCamCtrl->mPreviewMemoryLock.lock();
    201 	for (int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) {
    202         mHalCamCtrl->mPreviewMemory.camera_memory[cnt]->release(mHalCamCtrl->mPreviewMemory.camera_memory[cnt]);
    203 #ifdef USE_ION
    204         struct ion_handle_data ion_handle;
    205         memset(&ion_handle, 0, sizeof(ion_handle));
    206         ion_handle.handle = mHalCamCtrl->mPreviewMemory.mem_info[cnt].handle;
    207         if (ioctl(mHalCamCtrl->mPreviewMemory.mem_info[cnt].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
    208             ALOGE("%s: ion free failed\n", __func__);
    209         }
    210         close(mHalCamCtrl->mPreviewMemory.mem_info[cnt].main_ion_fd);
    211 #endif
    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, handle =%p", __FUNCTION__, (*(mHalCamCtrl->mPreviewMemory.buffer_handle[cnt])));
    217               continue;
    218           } else {
    219 
    220             ALOGD("%s: genlock_unlock_buffer, handle =%p", __FUNCTION__, (*(mHalCamCtrl->mPreviewMemory.buffer_handle[cnt])));
    221               mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_UNLOCKED;
    222           }
    223         }
    224         if( mHalCamCtrl->mPreviewMemory.local_flag[cnt] != BUFFER_NOT_OWNED) {
    225             if (mHalCamCtrl->mPreviewWindow) {
    226                 err = mHalCamCtrl->mPreviewWindow->cancel_buffer(mHalCamCtrl->mPreviewWindow,
    227                                                                  mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
    228                 ALOGD("%s: cancel_buffer: hdl =%p", __func__,  (*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]));
    229             } else {
    230                 ALOGE("%s: Preview window is NULL, cannot cancel_buffer: hdl =%p",
    231                       __func__,  (*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]));
    232             }
    233         }
    234         mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_NOT_OWNED;
    235 		ALOGD(" put buffer %d successfully", cnt);
    236 	}
    237     mHalCamCtrl->mPreviewMemoryLock.unlock();
    238 	memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory));
    239     ALOGI(" %s : X ",__FUNCTION__);
    240     return NO_ERROR;
    241 }
    242 
    243 status_t QCameraStream_preview::initStream(uint8_t no_cb_needed, uint8_t stream_on)
    244 {
    245     int format = 0;
    246     status_t ret = NO_ERROR;
    247     int numMinUndequeuedBufs;
    248     int err = 0;
    249 
    250     ALOGI(" %s : E ", __FUNCTION__);
    251     if (mHalCamCtrl->isNoDisplayMode()) {
    252         mNumBuffers = PREVIEW_BUFFER_COUNT;
    253         if(mHalCamCtrl->isZSLMode()) {
    254             if(mNumBuffers < mHalCamCtrl->getZSLQueueDepth() + 3) {
    255                 mNumBuffers = mHalCamCtrl->getZSLQueueDepth() + 3;
    256             }
    257         }
    258     } else {
    259         if( mHalCamCtrl->mPreviewWindow == NULL) {
    260             ALOGE("%s: PreviewWindow = NULL", __func__);
    261             return INVALID_OPERATION;
    262         }
    263         numMinUndequeuedBufs = 0;
    264         if(mHalCamCtrl->mPreviewWindow->get_min_undequeued_buffer_count) {
    265             err = mHalCamCtrl->mPreviewWindow->get_min_undequeued_buffer_count(
    266                             mHalCamCtrl->mPreviewWindow, &numMinUndequeuedBufs);
    267             if (err != 0) {
    268                 ALOGE("get_min_undequeued_buffer_count  failed: %s (%d)",
    269                       strerror(-err), -err);
    270                 ret = UNKNOWN_ERROR;
    271                 goto end;
    272             }
    273         }
    274         mNumBuffers = PREVIEW_BUFFER_COUNT + numMinUndequeuedBufs;
    275         if(mHalCamCtrl->isZSLMode()) {
    276           if(mHalCamCtrl->getZSLQueueDepth() > numMinUndequeuedBufs)
    277             mNumBuffers += mHalCamCtrl->getZSLQueueDepth() - numMinUndequeuedBufs;
    278         }
    279     }
    280     ret = QCameraStream::initStream(no_cb_needed, stream_on);
    281 end:
    282     ALOGI(" %s : X ", __FUNCTION__);
    283     return ret;
    284 }
    285 
    286 
    287 status_t  QCameraStream_preview::getBufferNoDisplay( )
    288 {
    289     status_t ret = NO_ERROR;
    290     uint32_t planes[VIDEO_MAX_PLANES];
    291 
    292     ALOGI("%s : E ", __FUNCTION__);
    293 
    294     mHalCamCtrl->mPreviewMemoryLock.lock();
    295     memset(mDisplayBuf, 0, sizeof(mDisplayBuf));
    296     if (mHalCamCtrl->initHeapMem(&mHalCamCtrl->mNoDispPreviewMemory,
    297                                  mNumBuffers,
    298                                  mFrameOffsetInfo.frame_len,
    299                                  MSM_PMEM_MAINIMG,
    300                                  &mFrameOffsetInfo,
    301                                  mDisplayBuf) < 0) {
    302         ret = NO_MEMORY;
    303         goto end;
    304     }
    305 
    306     memset(&mHalCamCtrl->mMetadata, 0, sizeof(mHalCamCtrl->mMetadata));
    307     memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace));
    308 
    309     ALOGI(" %s : X ",__FUNCTION__);
    310 end:
    311     mHalCamCtrl->mPreviewMemoryLock.unlock();
    312     return ret;
    313 }
    314 
    315 status_t QCameraStream_preview::freeBufferNoDisplay()
    316 {
    317     ALOGI(" %s : E ", __FUNCTION__);
    318     mHalCamCtrl->mPreviewMemoryLock.lock();
    319     mHalCamCtrl->releaseHeapMem(&mHalCamCtrl->mNoDispPreviewMemory);
    320     memset(&mHalCamCtrl->mNoDispPreviewMemory, 0, sizeof(mHalCamCtrl->mNoDispPreviewMemory));
    321     mHalCamCtrl->mPreviewMemoryLock.unlock();
    322     ALOGI(" %s : X ",__FUNCTION__);
    323     return NO_ERROR;
    324 }
    325 
    326 void QCameraStream_preview::notifyROIEvent(fd_roi_t roi)
    327 {
    328     switch (roi.type) {
    329     case FD_ROI_TYPE_HEADER:
    330         {
    331             mDisplayLock.lock();
    332             mNumFDRcvd = 0;
    333             memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace));
    334             mHalCamCtrl->mMetadata.faces = mHalCamCtrl->mFace;
    335             mHalCamCtrl->mMetadata.number_of_faces = roi.d.hdr.num_face_detected;
    336             if(mHalCamCtrl->mMetadata.number_of_faces > MAX_ROI)
    337               mHalCamCtrl->mMetadata.number_of_faces = MAX_ROI;
    338             mDisplayLock.unlock();
    339 
    340             if (mHalCamCtrl->mMetadata.number_of_faces == 0) {
    341                 // Clear previous faces
    342                 if (mHalCamCtrl->mDataCb && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA)){
    343                     ALOGE("%s: Face detection RIO callback", __func__);
    344                     mHalCamCtrl->mDataCb(CAMERA_MSG_PREVIEW_METADATA, NULL, 0,
    345                         &mHalCamCtrl->mMetadata, mHalCamCtrl->mCallbackCookie);
    346                 }
    347             }
    348         }
    349         break;
    350     case FD_ROI_TYPE_DATA:
    351         {
    352             mDisplayLock.lock();
    353             int idx = roi.d.data.idx;
    354             if (idx >= mHalCamCtrl->mMetadata.number_of_faces) {
    355                 mDisplayLock.unlock();
    356                 ALOGE("%s: idx %d out of boundary %d",
    357                       __func__, idx, mHalCamCtrl->mMetadata.number_of_faces);
    358                 break;
    359             }
    360 
    361             mHalCamCtrl->mFace[idx].id = roi.d.data.face.id;
    362             mHalCamCtrl->mFace[idx].score = roi.d.data.face.score;
    363 
    364             // top
    365             mHalCamCtrl->mFace[idx].rect[0] =
    366                roi.d.data.face.face_boundary.x*2000/mHalCamCtrl->mDimension.display_width - 1000;
    367             //right
    368             mHalCamCtrl->mFace[idx].rect[1] =
    369                roi.d.data.face.face_boundary.y*2000/mHalCamCtrl->mDimension.display_height - 1000;
    370             //bottom
    371             mHalCamCtrl->mFace[idx].rect[2] =  mHalCamCtrl->mFace[idx].rect[0] +
    372                roi.d.data.face.face_boundary.dx*2000/mHalCamCtrl->mDimension.display_width;
    373             //left
    374             mHalCamCtrl->mFace[idx].rect[3] = mHalCamCtrl->mFace[idx].rect[1] +
    375                roi.d.data.face.face_boundary.dy*2000/mHalCamCtrl->mDimension.display_height;
    376 
    377             // Center of left eye
    378             mHalCamCtrl->mFace[idx].left_eye[0] =
    379               roi.d.data.face.left_eye_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000;
    380             mHalCamCtrl->mFace[idx].left_eye[1] =
    381               roi.d.data.face.left_eye_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000;
    382 
    383             // Center of right eye
    384             mHalCamCtrl->mFace[idx].right_eye[0] =
    385               roi.d.data.face.right_eye_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000;
    386             mHalCamCtrl->mFace[idx].right_eye[1] =
    387               roi.d.data.face.right_eye_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000;
    388 
    389             // Center of mouth
    390             mHalCamCtrl->mFace[idx].mouth[0] =
    391               roi.d.data.face.mouth_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000;
    392             mHalCamCtrl->mFace[idx].mouth[1] =
    393               roi.d.data.face.mouth_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000;
    394 
    395             mHalCamCtrl->mFace[idx].smile_degree = roi.d.data.face.smile_degree;
    396             mHalCamCtrl->mFace[idx].smile_score = roi.d.data.face.smile_confidence;
    397             mHalCamCtrl->mFace[idx].blink_detected = roi.d.data.face.blink_detected;
    398             mHalCamCtrl->mFace[idx].face_recognised = roi.d.data.face.is_face_recognised;
    399             mHalCamCtrl->mFace[idx].gaze_angle = roi.d.data.face.gaze_angle;
    400 
    401             /* newly added */
    402             // upscale by 2 to recover from demaen downscaling
    403             mHalCamCtrl->mFace[idx].updown_dir = roi.d.data.face.updown_dir * 2;
    404             mHalCamCtrl->mFace[idx].leftright_dir = roi.d.data.face.leftright_dir * 2;
    405             mHalCamCtrl->mFace[idx].roll_dir = roi.d.data.face.roll_dir * 2;
    406 
    407             mHalCamCtrl->mFace[idx].leye_blink = roi.d.data.face.left_blink;
    408             mHalCamCtrl->mFace[idx].reye_blink = roi.d.data.face.right_blink;
    409             mHalCamCtrl->mFace[idx].left_right_gaze = roi.d.data.face.left_right_gaze;
    410             mHalCamCtrl->mFace[idx].top_bottom_gaze = roi.d.data.face.top_bottom_gaze;
    411             ALOGE("%s: Face(%d, %d, %d, %d), leftEye(%d, %d), rightEye(%d, %d), mouth(%d, %d), smile(%d, %d), face_recg(%d)", __func__,
    412                mHalCamCtrl->mFace[idx].rect[0],  mHalCamCtrl->mFace[idx].rect[1],
    413                mHalCamCtrl->mFace[idx].rect[2],  mHalCamCtrl->mFace[idx].rect[3],
    414                mHalCamCtrl->mFace[idx].left_eye[0], mHalCamCtrl->mFace[idx].left_eye[1],
    415                mHalCamCtrl->mFace[idx].right_eye[0], mHalCamCtrl->mFace[idx].right_eye[1],
    416                mHalCamCtrl->mFace[idx].mouth[0], mHalCamCtrl->mFace[idx].mouth[1],
    417                mHalCamCtrl->mFace[idx].smile_degree, mHalCamCtrl->mFace[idx].smile_score,
    418                mHalCamCtrl->mFace[idx].face_recognised);
    419             ALOGE("%s: gaze(%d, %d, %d), updown(%d), leftright(%d), roll(%d), blink(%d, %d, %d)", __func__,
    420                mHalCamCtrl->mFace[idx].gaze_angle,  mHalCamCtrl->mFace[idx].left_right_gaze,
    421                mHalCamCtrl->mFace[idx].top_bottom_gaze,  mHalCamCtrl->mFace[idx].updown_dir,
    422                mHalCamCtrl->mFace[idx].leftright_dir, mHalCamCtrl->mFace[idx].roll_dir,
    423                mHalCamCtrl->mFace[idx].blink_detected,
    424                mHalCamCtrl->mFace[idx].leye_blink, mHalCamCtrl->mFace[idx].reye_blink);
    425 
    426              mNumFDRcvd++;
    427              mDisplayLock.unlock();
    428 
    429              if (mNumFDRcvd == mHalCamCtrl->mMetadata.number_of_faces) {
    430                  if (mHalCamCtrl->mDataCb && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA)){
    431                      ALOGE("%s: Face detection RIO callback with %d faces detected (score=%d)", __func__, mNumFDRcvd, mHalCamCtrl->mFace[idx].score);
    432                      mHalCamCtrl->mDataCb(CAMERA_MSG_PREVIEW_METADATA, NULL,
    433                                           0, &mHalCamCtrl->mMetadata, mHalCamCtrl->mCallbackCookie);
    434                  }
    435              }
    436         }
    437         break;
    438     }
    439 }
    440 
    441 status_t QCameraStream_preview::initDisplayBuffers()
    442 {
    443   status_t ret = NO_ERROR;
    444   uint8_t num_planes = mFrameOffsetInfo.num_planes;
    445   uint32_t planes[VIDEO_MAX_PLANES];
    446 
    447   ALOGI("%s:BEGIN",__func__);
    448   memset(&mHalCamCtrl->mMetadata, 0, sizeof(camera_frame_metadata_t));
    449   mHalCamCtrl->mPreviewMemoryLock.lock();
    450   memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory));
    451   mHalCamCtrl->mPreviewMemoryLock.unlock();
    452   memset(mNotifyBuffer, 0, sizeof(mNotifyBuffer));
    453 
    454   ret = getBufferFromSurface();
    455   if(ret != NO_ERROR) {
    456     ALOGE("%s: cannot get memory from surface texture client, ret = %d", __func__, ret);
    457     return ret;
    458   }
    459 
    460   /* set 4 buffers for display */
    461   mHalCamCtrl->mPreviewMemoryLock.lock();
    462   for(int i=0; i < num_planes; i++)
    463       planes[i] = mFrameOffsetInfo.mp[i].len;
    464   memset(mDisplayBuf, 0, sizeof(mm_camera_buf_def_t) * 2 * PREVIEW_BUFFER_COUNT);
    465   /*allocate memory for the buffers*/
    466   for(int i = 0; i < mNumBuffers; i++){
    467 	  if (mHalCamCtrl->mPreviewMemory.private_buffer_handle[i] == NULL)
    468 		  continue;
    469 	  mHalCamCtrl->mPreviewMemory.addr_offset[i] =
    470 	      mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->offset;
    471     ALOGD("%s: idx = %d, fd = %d, size = %d, cbcr_offset = %d, y_offset = %d, "
    472       "offset = %d, vaddr = 0x%lx", __func__, i, mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->fd,
    473       mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size,
    474       planes[0], 0,
    475       mHalCamCtrl->mPreviewMemory.addr_offset[i],
    476       (long unsigned int)mHalCamCtrl->mPreviewMemory.camera_memory[i]->data);
    477     mDisplayBuf[i].num_planes = num_planes;
    478 
    479     /* Plane 0 needs to be set seperately. Set other planes
    480      * in a loop. */
    481     mDisplayBuf[i].planes[0].length = planes[0];
    482     mDisplayBuf[i].planes[0].m.userptr = mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->fd;
    483     mDisplayBuf[i].planes[0].data_offset = mFrameOffsetInfo.mp[0].offset;
    484     mDisplayBuf[i].planes[0].reserved[0] =0;// mHalCamCtrl->mPreviewMemory.addr_offset[i]; //     mDisplayBuf.preview.buf.mp[i].frame_offset;
    485     for (int j = 1; j < num_planes; j++) {
    486       mDisplayBuf[i].planes[j].length = planes[j];
    487       mDisplayBuf[i].planes[j].m.userptr = mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->fd;
    488       mDisplayBuf[i].planes[j].data_offset = mFrameOffsetInfo.mp[j].offset;
    489       mDisplayBuf[i].planes[j].reserved[0] =
    490         mDisplayBuf[i].planes[j-1].reserved[0] +
    491         mDisplayBuf[i].planes[j-1].length;
    492     }
    493 
    494     for (int j = 0; j < num_planes; j++)
    495       ALOGD("Planes: %d length: %d userptr: %lu offset: %d\n", j,
    496         mDisplayBuf[i].planes[j].length,
    497         mDisplayBuf[i].planes[j].m.userptr,
    498         mDisplayBuf[i].planes[j].reserved[0]);
    499 
    500     mDisplayBuf[i].fd = mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->fd;
    501     ALOGD("DEBUG2:Display buf[%d] fd:%d",i,mDisplayBuf[i].fd);
    502     mDisplayBuf[i].frame_len = mFrameOffsetInfo.frame_len;
    503     mDisplayBuf[i].buffer = (void *)mHalCamCtrl->mPreviewMemory.camera_memory[i]->data;
    504     mDisplayBuf[i].mem_info = (void *)&mHalCamCtrl->mPreviewMemory.mem_info[i];
    505   }/*end of for loop*/
    506 
    507  /* register the streaming buffers for the channel*/
    508   mHalCamCtrl->mPreviewMemoryLock.unlock();
    509   ALOGI("%s:END",__func__);
    510   return NO_ERROR;
    511 
    512 error:
    513     mHalCamCtrl->mPreviewMemoryLock.unlock();
    514     putBufferToSurface();
    515 
    516     ALOGV("%s: X", __func__);
    517     return ret;
    518 }
    519 
    520 status_t QCameraStream_preview::initPreviewOnlyBuffers()
    521 {
    522     status_t ret = NO_ERROR;
    523     uint8_t num_planes = mFrameOffsetInfo.num_planes;
    524     uint32_t planes[VIDEO_MAX_PLANES];
    525 
    526     ALOGI("%s:BEGIN",__func__);
    527     memset(&mHalCamCtrl->mMetadata, 0, sizeof(camera_frame_metadata_t));
    528     mHalCamCtrl->mPreviewMemoryLock.lock();
    529     memset(&mHalCamCtrl->mNoDispPreviewMemory, 0, sizeof(mHalCamCtrl->mNoDispPreviewMemory));
    530     mHalCamCtrl->mPreviewMemoryLock.unlock();
    531 
    532     memset(mNotifyBuffer, 0, sizeof(mNotifyBuffer));
    533     memset(mDisplayBuf, 0, sizeof(mDisplayBuf));
    534 
    535     ret = getBufferNoDisplay( );
    536     if(ret != NO_ERROR) {
    537         ALOGE("%s: cannot get memory from surface texture client, ret = %d", __func__, ret);
    538         return ret;
    539     }
    540 
    541     ALOGI("%s:END",__func__);
    542     return NO_ERROR;
    543 }
    544 
    545 
    546 void QCameraStream_preview::dumpFrameToFile(mm_camera_buf_def_t *newFrame)
    547 {
    548   int32_t enabled = 0;
    549   int frm_num;
    550   uint32_t  skip_mode;
    551   char value[PROPERTY_VALUE_MAX];
    552   char buf[32];
    553   int w, h;
    554   static int count = 0;
    555   cam_ctrl_dimension_t dim;
    556   int file_fd;
    557   int rc = 0;
    558   int len;
    559   unsigned long addr;
    560   unsigned long * tmp = (unsigned long *)newFrame->buffer;
    561   addr = *tmp;
    562   status_t ret = p_mm_ops->ops->get_parm(mCameraHandle,
    563                  MM_CAMERA_PARM_DIMENSION, &dim);
    564 
    565   w = dim.display_width;
    566   h = dim.display_height;
    567   len = (w * h)*3/2;
    568   count++;
    569   if(count < 100) {
    570     snprintf(buf, sizeof(buf), "/data/mzhu%d.yuv", count);
    571     file_fd = open(buf, O_RDWR | O_CREAT, 0777);
    572 
    573     rc = write(file_fd, (const void *)addr, len);
    574     ALOGE("%s: file='%s', vaddr_old=0x%x, addr_map = 0x%p, len = %d, rc = %d",
    575           __func__, buf, (uint32_t)newFrame->buffer, (void *)addr, len, rc);
    576     close(file_fd);
    577     ALOGE("%s: dump %s, rc = %d, len = %d", __func__, buf, rc, len);
    578   }
    579 }
    580 
    581 status_t QCameraStream_preview::processPreviewFrameWithDisplay(mm_camera_super_buf_t *frame)
    582 {
    583   ALOGV("%s",__func__);
    584   int err = 0;
    585   int msgType = 0;
    586   int i;
    587   camera_memory_t *data = NULL;
    588   camera_frame_metadata_t *metadata = NULL;
    589   int preview_buf_idx = frame->bufs[0]->buf_idx;
    590 
    591   if(!mActive) {
    592     ALOGE("Preview Stopped. Returning callback");
    593     return NO_ERROR;
    594   }
    595 
    596   if(mHalCamCtrl==NULL) {
    597     ALOGE("%s: X: HAL control object not set",__func__);
    598     /*Call buf done*/
    599     return BAD_VALUE;
    600   }
    601 
    602   if(mFirstFrameRcvd == false) {
    603       mFirstFrameRcvd = true;
    604   }
    605 
    606   if (UNLIKELY(mHalCamCtrl->mDebugFps)) {
    607       mHalCamCtrl->debugShowPreviewFPS();
    608   }
    609   mHalCamCtrl->dumpFrameToFile(frame->bufs[0], HAL_DUMP_FRM_PREVIEW);
    610 
    611   mHalCamCtrl->mPreviewMemoryLock.lock();
    612   mNotifyBuffer[preview_buf_idx] = *frame;
    613 
    614   ALOGD("<DEBUG2>: Received Frame fd:%d placed in index:%d db[index].fd:%d",
    615         frame->bufs[0]->fd, preview_buf_idx,
    616         mHalCamCtrl->mPreviewMemory.private_buffer_handle[preview_buf_idx]->fd);
    617 
    618   ALOGI("Enqueue buf handle %p\n",
    619   mHalCamCtrl->mPreviewMemory.buffer_handle[preview_buf_idx]);
    620   ALOGD("%s: camera call genlock_unlock", __FUNCTION__);
    621   if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[preview_buf_idx]) {
    622     ALOGD("%s: genlock_unlock_buffer hdl =%p", __FUNCTION__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[preview_buf_idx]));
    623       if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t*)
    624 	            (*mHalCamCtrl->mPreviewMemory.buffer_handle[preview_buf_idx]))) {
    625             ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
    626       } else {
    627           mHalCamCtrl->mPreviewMemory.local_flag[preview_buf_idx] = BUFFER_UNLOCKED;
    628       }
    629     } else {
    630         ALOGE("%s: buffer to be enqueued is not locked", __FUNCTION__);
    631   }
    632 
    633   mHalCamCtrl->cache_ops(&mHalCamCtrl->mPreviewMemory.mem_info[preview_buf_idx],
    634                          (void *)mHalCamCtrl->mPreviewMemory.camera_memory[preview_buf_idx]->data,
    635                          ION_IOC_CLEAN_CACHES);
    636   mHalCamCtrl->cache_ops(&mHalCamCtrl->mPreviewMemory.mem_info[preview_buf_idx],
    637                          (void *)mHalCamCtrl->mPreviewMemory.camera_memory[preview_buf_idx]->data,
    638                          ION_IOC_CLEAN_INV_CACHES);
    639 
    640   if(mHFRFrameSkip == 1)
    641   {
    642       ALOGE("In HFR Frame skip");
    643       const char *str = mHalCamCtrl->mParameters.get(
    644                           QCameraParameters::KEY_QC_VIDEO_HIGH_FRAME_RATE);
    645       if(str != NULL){
    646       int is_hfr_off = 0;
    647       mHFRFrameCnt++;
    648       if(!strcmp(str, QCameraParameters::VIDEO_HFR_OFF)) {
    649           is_hfr_off = 1;
    650           err = mHalCamCtrl->mPreviewWindow->enqueue_buffer(mHalCamCtrl->mPreviewWindow,
    651             (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[preview_buf_idx]);
    652       } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_2X)) {
    653           mHFRFrameCnt %= 2;
    654       } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_3X)) {
    655           mHFRFrameCnt %= 3;
    656       } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_4X)) {
    657           mHFRFrameCnt %= 4;
    658       }
    659       if(mHFRFrameCnt == 0)
    660           err = mHalCamCtrl->mPreviewWindow->enqueue_buffer(mHalCamCtrl->mPreviewWindow,
    661             (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[preview_buf_idx]);
    662       else if(!is_hfr_off)
    663           err = mHalCamCtrl->mPreviewWindow->cancel_buffer(mHalCamCtrl->mPreviewWindow,
    664             (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[preview_buf_idx]);
    665       } else
    666           err = mHalCamCtrl->mPreviewWindow->enqueue_buffer(mHalCamCtrl->mPreviewWindow,
    667             (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[preview_buf_idx]);
    668   } else {
    669       err = mHalCamCtrl->mPreviewWindow->enqueue_buffer(mHalCamCtrl->mPreviewWindow,
    670           (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[preview_buf_idx]);
    671   }
    672   if(err != 0) {
    673     ALOGE("%s: enqueue_buffer failed, err = %d", __func__, err);
    674   } else {
    675    ALOGD("%s: enqueue_buffer hdl=%p", __func__, *mHalCamCtrl->mPreviewMemory.buffer_handle[preview_buf_idx]);
    676     mHalCamCtrl->mPreviewMemory.local_flag[preview_buf_idx] = BUFFER_NOT_OWNED;
    677   }
    678   buffer_handle_t *buffer_handle = NULL;
    679   int tmp_stride = 0;
    680   err = mHalCamCtrl->mPreviewWindow->dequeue_buffer(mHalCamCtrl->mPreviewWindow,
    681               &buffer_handle, &tmp_stride);
    682   if (err == NO_ERROR && buffer_handle != NULL) {
    683 
    684     ALOGD("%s: dequed buf hdl =%p", __func__, *buffer_handle);
    685     for(i = 0; i < mHalCamCtrl->mPreviewMemory.buffer_count; i++) {
    686         if(mHalCamCtrl->mPreviewMemory.buffer_handle[i] == buffer_handle) {
    687           ALOGE("<DEBUG2>:Found buffer in idx:%d",i);
    688           mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_UNLOCKED;
    689           break;
    690         }
    691     }
    692      if (i < mHalCamCtrl->mPreviewMemory.buffer_count ) {
    693       err = mHalCamCtrl->mPreviewWindow->lock_buffer(mHalCamCtrl->mPreviewWindow, buffer_handle);
    694       ALOGD("%s: camera call genlock_lock: hdl =%p", __func__, *buffer_handle);
    695       if (GENLOCK_FAILURE == genlock_lock_buffer((native_handle_t*)(*buffer_handle), GENLOCK_WRITE_LOCK,
    696                                                  GENLOCK_MAX_TIMEOUT)) {
    697             ALOGE("%s: genlock_lock_buffer(WRITE) failed", __func__);
    698       } else  {
    699         mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_LOCKED;
    700 
    701         if(MM_CAMERA_OK != p_mm_ops->ops->qbuf(mCameraHandle, mChannelId, mNotifyBuffer[i].bufs[0])) {
    702 
    703             ALOGE("BUF DONE FAILED");
    704         }
    705         mHalCamCtrl->cache_ops((QCameraHalMemInfo_t *)(mNotifyBuffer[i].bufs[0]->mem_info),
    706                                mNotifyBuffer[i].bufs[0]->buffer,
    707                                ION_IOC_INV_CACHES);
    708         }
    709      }
    710   } else
    711       ALOGE("%s: enqueue_buffer idx = %d, no free buffer from display now", __func__, frame->bufs[0]->buf_idx);
    712   /* Save the last displayed frame. We'll be using it to fill the gap between
    713      when preview stops and postview start during snapshot.*/
    714   mLastQueuedFrame = &(mDisplayBuf[preview_buf_idx]);
    715   mHalCamCtrl->mPreviewMemoryLock.unlock();
    716 
    717   nsecs_t timeStamp = seconds_to_nanoseconds(frame->bufs[0]->ts.tv_sec) ;
    718   timeStamp += frame->bufs[0]->ts.tv_nsec;
    719   ALOGD("Message enabled = 0x%x", mHalCamCtrl->mMsgEnabled);
    720 
    721   camera_memory_t *previewMem = NULL;
    722 
    723   if (mHalCamCtrl->mDataCb != NULL) {
    724        ALOGD("%s: mMsgEnabled =0x%x, preview format =%d", __func__,
    725             mHalCamCtrl->mMsgEnabled, mHalCamCtrl->mPreviewFormat);
    726       //Sending preview callback if corresponding Msgs are enabled
    727       if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) {
    728           ALOGE("Q%s: PCB callback enabled", __func__);
    729           msgType |=  CAMERA_MSG_PREVIEW_FRAME;
    730           int previewBufSize;
    731           /* The preview buffer size sent back in the callback should be (width*height*bytes_per_pixel)
    732            * As all preview formats we support, use 12 bits per pixel, buffer size = previewWidth * previewHeight * 3/2.
    733            * We need to put a check if some other formats are supported in future. (punits) */
    734           if ((mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_NV21) ||
    735               (mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_NV12) ||
    736               (mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_YV12))
    737           {
    738               if(mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_YV12) {
    739                   previewBufSize = ((mHalCamCtrl->mPreviewWidth+15)/16) * 16 * mHalCamCtrl->mPreviewHeight +
    740                                    ((mHalCamCtrl->mPreviewWidth/2+15)/16) * 16* mHalCamCtrl->mPreviewHeight;
    741               } else {
    742                   previewBufSize = mHalCamCtrl->mPreviewWidth * mHalCamCtrl->mPreviewHeight * 3/2;
    743               }
    744               if(previewBufSize != mHalCamCtrl->mPreviewMemory.private_buffer_handle[preview_buf_idx]->size) {
    745                   previewMem = mHalCamCtrl->mGetMemory(mHalCamCtrl->mPreviewMemory.private_buffer_handle[preview_buf_idx]->fd,
    746                                                        previewBufSize, 1, mHalCamCtrl->mCallbackCookie);
    747                   if (!previewMem || !previewMem->data) {
    748                       ALOGE("%s: mGetMemory failed.\n", __func__);
    749                   } else {
    750                       data = previewMem;
    751                   }
    752               } else
    753                     data = mHalCamCtrl->mPreviewMemory.camera_memory[preview_buf_idx];
    754           } else {
    755                 data = mHalCamCtrl->mPreviewMemory.camera_memory[preview_buf_idx];
    756                 ALOGE("Invalid preview format, buffer size in preview callback may be wrong.");
    757           }
    758       } else {
    759           data = NULL;
    760       }
    761       if(msgType && mActive) {
    762           mHalCamCtrl->mDataCb(msgType, data, 0, metadata, mHalCamCtrl->mCallbackCookie);
    763       }
    764       if (previewMem) {
    765           previewMem->release(previewMem);
    766       }
    767 	  ALOGD("end of cb");
    768   } else {
    769     ALOGD("%s PCB is not enabled", __func__);
    770   }
    771   if(mHalCamCtrl->mDataCbTimestamp != NULL && mVFEOutputs == 1)
    772   {
    773       int flagwait = 1;
    774       if(mHalCamCtrl->mStartRecording == true &&
    775               ( mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME))
    776       {
    777         if (mHalCamCtrl->mStoreMetaDataInFrame)
    778         {
    779           if(mHalCamCtrl->mRecordingMemory.metadata_memory[preview_buf_idx])
    780           {
    781               flagwait = 1;
    782               mHalCamCtrl->mDataCbTimestamp(timeStamp, CAMERA_MSG_VIDEO_FRAME,
    783                                             mHalCamCtrl->mRecordingMemory.metadata_memory[preview_buf_idx],
    784                                             0, mHalCamCtrl->mCallbackCookie);
    785           }else
    786               flagwait = 0;
    787       }
    788       else
    789       {
    790           mHalCamCtrl->mDataCbTimestamp(timeStamp, CAMERA_MSG_VIDEO_FRAME,
    791                                         mHalCamCtrl->mPreviewMemory.camera_memory[preview_buf_idx],
    792                                         0, mHalCamCtrl->mCallbackCookie);
    793       }
    794 
    795       if(flagwait){
    796           Mutex::Autolock rLock(&mHalCamCtrl->mRecordFrameLock);
    797           if (mHalCamCtrl->mReleasedRecordingFrame != true) {
    798               mHalCamCtrl->mRecordWait.wait(mHalCamCtrl->mRecordFrameLock);
    799           }
    800           mHalCamCtrl->mReleasedRecordingFrame = false;
    801       }
    802       }
    803   }
    804   return NO_ERROR;
    805 }
    806 
    807 
    808 status_t QCameraStream_preview::processPreviewFrameWithOutDisplay(
    809   mm_camera_super_buf_t *frame)
    810 {
    811   ALOGV("%s",__func__);
    812   int err = 0;
    813   int msgType = 0;
    814   int i;
    815   camera_memory_t *data = NULL;
    816   camera_frame_metadata_t *metadata = NULL;
    817   int preview_buf_idx = frame->bufs[0]->buf_idx;
    818 
    819   if(mHalCamCtrl==NULL) {
    820     ALOGE("%s: X: HAL control object not set",__func__);
    821     /*Call buf done*/
    822     return BAD_VALUE;
    823   }
    824 
    825   if (UNLIKELY(mHalCamCtrl->mDebugFps)) {
    826       mHalCamCtrl->debugShowPreviewFPS();
    827   }
    828   mHalCamCtrl->dumpFrameToFile(frame->bufs[0], HAL_DUMP_FRM_PREVIEW);
    829 
    830   mHalCamCtrl->mPreviewMemoryLock.lock();
    831   mNotifyBuffer[preview_buf_idx] = *frame;
    832 
    833   /* Save the last displayed frame. We'll be using it to fill the gap between
    834      when preview stops and postview start during snapshot.*/
    835   mLastQueuedFrame = &(mDisplayBuf[frame->bufs[0]->buf_idx]);
    836   mHalCamCtrl->mPreviewMemoryLock.unlock();
    837 
    838   ALOGD("Message enabled = 0x%x", mHalCamCtrl->mMsgEnabled);
    839 
    840   mHalCamCtrl->cache_ops(&mHalCamCtrl->mNoDispPreviewMemory.mem_info[preview_buf_idx],
    841                          (void *)mHalCamCtrl->mNoDispPreviewMemory.camera_memory[preview_buf_idx]->data,
    842                          ION_IOC_CLEAN_CACHES);
    843 
    844   if (mHalCamCtrl->mDataCb != NULL) {
    845       //Sending preview callback if corresponding Msgs are enabled
    846       if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) {
    847           msgType |=  CAMERA_MSG_PREVIEW_FRAME;
    848           int previewBufSize;
    849           /* For CTS : Forcing preview memory buffer lenth to be
    850              'previewWidth * previewHeight * 3/2'.
    851               Needed when gralloc allocated extra memory.*/
    852           //Can add this check for other formats as well.
    853         data = mHalCamCtrl->mNoDispPreviewMemory.camera_memory[preview_buf_idx];//mPreviewHeap->mBuffers[frame->bufs[0]->buf_idx];
    854       } else {
    855           data = NULL;
    856       }
    857 
    858       if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA){
    859           msgType  |= CAMERA_MSG_PREVIEW_METADATA;
    860           metadata = &mHalCamCtrl->mMetadata;
    861       } else {
    862           metadata = NULL;
    863       }
    864       if(mActive && msgType) {
    865           mHalCamCtrl->mDataCb(msgType, data, 0, metadata, mHalCamCtrl->mCallbackCookie);
    866       }
    867 
    868       if(MM_CAMERA_OK !=p_mm_ops->ops->qbuf(mCameraHandle, mChannelId, mNotifyBuffer[preview_buf_idx].bufs[0])) {
    869           ALOGE("BUF DONE FAILED");
    870       }
    871       mHalCamCtrl->cache_ops((QCameraHalMemInfo_t *)(mNotifyBuffer[preview_buf_idx].bufs[0]->mem_info),
    872                              mNotifyBuffer[preview_buf_idx].bufs[0]->buffer,
    873                              ION_IOC_INV_CACHES);
    874       ALOGD("end of cb");
    875   }
    876 
    877   return NO_ERROR;
    878 }
    879 
    880 status_t QCameraStream_preview::processPreviewFrame (
    881   mm_camera_super_buf_t *frame)
    882 {
    883   if (mHalCamCtrl->isNoDisplayMode()) {
    884     return processPreviewFrameWithOutDisplay(frame);
    885   } else {
    886     return processPreviewFrameWithDisplay(frame);
    887   }
    888 }
    889 
    890 // ---------------------------------------------------------------------------
    891 // QCameraStream_preview
    892 // ---------------------------------------------------------------------------
    893 
    894 QCameraStream_preview::QCameraStream_preview(uint32_t CameraHandle,
    895                                              uint32_t ChannelId,
    896                                              uint32_t Width,
    897                                              uint32_t Height,
    898                                              uint32_t Format,
    899                                              uint8_t NumBuffers,
    900                                              mm_camera_vtbl_t *mm_ops,
    901                                              mm_camera_img_mode imgmode,
    902                                              camera_mode_t mode,
    903                                              QCameraHardwareInterface* camCtrl)
    904   :QCameraStream(CameraHandle,
    905                  ChannelId,
    906                  Width,
    907                  Height,
    908                  Format,
    909                  NumBuffers,
    910                  mm_ops,
    911                  imgmode,
    912                  mode,
    913                  camCtrl),
    914     mLastQueuedFrame(NULL),
    915     mNumFDRcvd(0)
    916   {
    917   }
    918 // ---------------------------------------------------------------------------
    919 // QCameraStream_preview
    920 // ---------------------------------------------------------------------------
    921 
    922 QCameraStream_preview::~QCameraStream_preview() {
    923     ALOGV("%s: E", __func__);
    924     release();
    925     ALOGV("%s: X", __func__);
    926 
    927 }
    928 
    929 // ---------------------------------------------------------------------------
    930 // QCameraStream_preview
    931 // ---------------------------------------------------------------------------
    932 void QCameraStream_preview::release() {
    933     streamOff(0);
    934     deinitStream();
    935 }
    936 
    937 void *QCameraStream_preview::getLastQueuedFrame(void)
    938 {
    939     return mLastQueuedFrame;
    940 }
    941 
    942 int32_t QCameraStream_preview::setCrop()
    943 {
    944     int32_t rc = QCameraStream::setCrop();
    945     if (0 == rc) {
    946         if (!mHalCamCtrl->mSmoothZoomRunning && mHalCamCtrl->mPreviewWindow) {
    947             rc = mHalCamCtrl->mPreviewWindow->set_crop(
    948                             mHalCamCtrl->mPreviewWindow,
    949                             mCrop.offset_x,
    950                             mCrop.offset_y,
    951                             mCrop.offset_x + mCrop.width,
    952                             mCrop.offset_y + mCrop.height);
    953         }
    954     }
    955     return rc;
    956 }
    957 
    958 int QCameraStream_preview::getBuf(mm_camera_frame_len_offset *frame_offset_info,
    959                               uint8_t num_bufs,
    960                               uint8_t *initial_reg_flag,
    961                               mm_camera_buf_def_t  *bufs)
    962 {
    963     int ret = 0;
    964     ALOGE("%s:BEGIN",__func__);
    965 
    966     if (num_bufs > mNumBuffers) {
    967         mNumBuffers = num_bufs;
    968     }
    969     if ((mNumBuffers == 0) || (mNumBuffers > MM_CAMERA_MAX_NUM_FRAMES)) {
    970         ALOGE("%s: Invalid number of buffers (=%d) requested!",
    971              __func__, mNumBuffers);
    972         return BAD_VALUE;
    973     }
    974 
    975     memcpy(&mFrameOffsetInfo, frame_offset_info, sizeof(mFrameOffsetInfo));
    976     if (mHalCamCtrl->isNoDisplayMode()) {
    977         ret = initPreviewOnlyBuffers();
    978     } else {
    979         ret = initDisplayBuffers();
    980     }
    981     ALOGD("Debug : %s : initDisplayBuffers",__func__);
    982     for(int i = 0; i < num_bufs; i++) {
    983         bufs[i] = mDisplayBuf[i];
    984         initial_reg_flag[i] = true;
    985     }
    986 
    987     ALOGV("%s: X - ret = %d ", __func__, ret);
    988     return ret;
    989 }
    990 
    991 int QCameraStream_preview::putBuf(uint8_t num_bufs, mm_camera_buf_def_t *bufs)
    992 {
    993     int ret = 0;
    994     ALOGE(" %s : E ", __func__);
    995     if (mHalCamCtrl->isNoDisplayMode()) {
    996         ret = freeBufferNoDisplay();
    997     } else {
    998         ret = putBufferToSurface();
    999     }
   1000     ALOGI(" %s : X ",__func__);
   1001     return ret;
   1002 }
   1003 
   1004 // ---------------------------------------------------------------------------
   1005 // No code beyone this line
   1006 // ---------------------------------------------------------------------------
   1007 }; // namespace android
   1008