Home | History | Annotate | Download | only in camera
      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 // ---------------------------------------------------------------------------
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
   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 
   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::
   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 
   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 
   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 
   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 // ---------------------------------------------------------------------------
   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 // ---------------------------------------------------------------------------
   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*
   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 
   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 */
   1498 void *QCameraStream_preview::getLastQueuedFrame(void)
   1499 {
   1500     return mLastQueuedFrame;
   1501 }
   1502 
   1503 // ---------------------------------------------------------------------------
   1504 // No code beyone this line
   1505 // ---------------------------------------------------------------------------
   1506 }; // namespace android
   1507