diff --git a/camera/QCameraHWI.cpp b/camera/QCameraHWI.cpp index e8759be5..81101a01 100755 --- a/camera/QCameraHWI.cpp +++ b/camera/QCameraHWI.cpp @@ -190,7 +190,9 @@ QCameraHardwareInterface(int cameraId, int mode) mReleasedRecordingFrame(false), mStateLiveshot(false), isCameraOpen(false), - mPauseFramedispatch(false) + mPauseFramedispatch(false), + mSnapJpegCbRunning(false), + mSnapCbDisabled(false) { ALOGV("QCameraHardwareInterface: E"); int32_t result = MM_CAMERA_E_GENERAL; @@ -332,9 +334,11 @@ QCameraHardwareInterface::~QCameraHardwareInterface() mStatHeap = NULL; } } + /*First stop the polling threads*/ + ALOGI("%s First stop the polling threads before deleting instances", __func__); + cam_ops_stop(mCameraId); /* Join the threads, complete operations and then delete the instances. */ - cam_ops_close(mCameraId); if(mStreamDisplay){ QCameraStream_preview::deleteInstance (mStreamDisplay); mStreamDisplay = NULL; @@ -358,6 +362,8 @@ QCameraHardwareInterface::~QCameraHardwareInterface() mStreamLiveSnap = NULL; } + /* Now close the camera after deleting all the instances */ + cam_ops_close(mCameraId); pthread_mutex_destroy(&mAsyncCmdMutex); pthread_cond_destroy(&mAsyncCmdWait); isCameraOpen = false; @@ -1562,8 +1568,21 @@ status_t QCameraHardwareInterface::cancelPicture() status_t QCameraHardwareInterface::cancelPictureInternal() { - ALOGV("cancelPictureInternal: E"); + ALOGI("cancelPictureInternal: E"); status_t ret = MM_CAMERA_OK; + // Do not need Snapshot callback to up layer any more + mSnapCbDisabled = true; + //we should make sure that snap_jpeg_cb has finished + if(mStreamSnap){ + mSnapJpegCbLock.lock(); + if(mSnapJpegCbRunning != false){ + ALOGE("%s: wait snapshot_jpeg_cb() to finish.", __func__); + mSnapJpegCbWait.wait(mSnapJpegCbLock); + ALOGE("%s: finish waiting snapshot_jpeg_cb(). ", __func__); + } + mSnapJpegCbLock.unlock(); + } + ALOGI("%s: mCameraState=%d.", __func__, mCameraState); if(mCameraState != CAMERA_STATE_READY) { if(mStreamSnap) { mStreamSnap->stop(); @@ -1639,6 +1658,23 @@ status_t QCameraHardwareInterface::takePicture() bool hdr; int frm_num = 1, rc = 0; int exp[MAX_HDR_EXP_FRAME_NUM]; + + mSnapJpegCbLock.lock(); + if(mSnapJpegCbRunning==true){ // This flag is set true in snapshot_jpeg_cb + ALOGE("%s: wait snapshot_jpeg_cb() to finish to proceed with the next take picture", __func__); + mSnapJpegCbWait.wait(mSnapJpegCbLock); + ALOGE("%s: finish waiting snapshot_jpeg_cb() ", __func__); + } + mSnapJpegCbLock.unlock(); + + // if we have liveSnapshot instance, + // we need to delete it here to release teh channel it acquires + if (NULL != mStreamLiveSnap) { + delete(mStreamLiveSnap); + mStreamLiveSnap = NULL; + } + + mSnapCbDisabled = false; if(QCAMERA_HAL_RECORDING_STARTED != mPreviewState){ isp3a_af_mode_t afMode = getAutoFocusMode(mParameters); @@ -1660,6 +1696,7 @@ status_t QCameraHardwareInterface::takePicture() ALOGE("%s: Failed to Check MM_CAMERA_PARM_LG_CAF_LOCK, rc %d", __func__, rc); } hdr = getHdrInfoAndSetExp(MAX_HDR_EXP_FRAME_NUM, &frm_num, exp); + mStreamSnap->resetSnapshotCounters(); mStreamSnap->InitHdrInfoForSnapshot(hdr, frm_num, exp); switch(mPreviewState) { diff --git a/camera/QCameraHWI.h b/camera/QCameraHWI.h old mode 100644 new mode 100755 index c9a7f3e9..4489a94f --- a/camera/QCameraHWI.h +++ b/camera/QCameraHWI.h @@ -849,6 +849,11 @@ class QCameraHardwareInterface : public virtual RefBase { int mNoDisplayMode; int mIsoValue; + /* Used to show the process state of snapshot_jpeg_cb*/ + Mutex mSnapJpegCbLock; + Condition mSnapJpegCbWait; + bool mSnapJpegCbRunning; + bool mSnapCbDisabled; }; }; // namespace android diff --git a/camera/QCameraHWI_Still.cpp b/camera/QCameraHWI_Still.cpp index 66ea6b9f..83bb783f 100755 --- a/camera/QCameraHWI_Still.cpp +++ b/camera/QCameraHWI_Still.cpp @@ -187,8 +187,9 @@ static void snapshot_jpeg_cb(jpeg_event_t event, void *user_data) } if (pme != NULL) { + pme->setSnapJpegCbState(true); pme->receiveCompleteJpegPicture(event); - ALOGV(" Completed issuing JPEG callback"); + ALOGI("Completed issuing JPEG callback"); /* deinit only if we are done taking requested number of snapshots */ if (pme->getSnapshotState() == SNAPSHOT_STATE_JPEG_COMPLETE_ENCODE_DONE) { ALOGV(" About to issue deinit callback"); @@ -199,6 +200,7 @@ static void snapshot_jpeg_cb(jpeg_event_t event, void *user_data) pme->stop(); } } + pme->setSnapJpegCbState(false); } else ALOGW("%s: Receive jpeg cb Obj Null", __func__); @@ -280,12 +282,26 @@ receiveCompleteJpegPicture(jpeg_event_t event) hdrJpegCount++; mStopCallbackLock.lock( ); - if(!mActive && !isLiveSnapshot()) { + ALOGV("%s after mStopCallbackLock.lock()", __func__); + // if(!mActive && !isLiveSnapshot() && !mHalCamCtrl->mSnapCbDisabled) { + if(mHalCamCtrl->mSnapCbDisabled) { ALOGE("%s : Cancel Picture",__func__); fail_cb_flag = true; - goto end; + mHalCamCtrl->deinitExifData(); + mBurstModeFlag = false; + //reset jpeg_offset + mJpegOffset = 0; + /* free the resource we allocated to maintain the structure */ + //mm_camera_do_munmap(main_fd, (void *)main_buffer_addr, mSnapshotStreamBuf.frame_len); + if(mCurrentFrameEncoded) { + free(mCurrentFrameEncoded); + mCurrentFrameEncoded = NULL; + } + // goto end; + mStopCallbackLock.unlock(); + return; } - + // mStopCallbackLock.lock( ); if(mCurrentFrameEncoded!=NULL /*&& !isLiveSnapshot()*/){ ALOGV(": Calling buf done for snapshot buffer"); cam_evt_buf_done(mCameraId, mCurrentFrameEncoded); @@ -351,11 +367,13 @@ receiveCompleteJpegPicture(jpeg_event_t event) */ jpg_data_cb = mHalCamCtrl->mDataCb; } - if(mHalCamCtrl->mHdrMode == HDR_MODE && (hdrJpegCount%2) != 0){ - mStopCallbackLock.unlock( ); - mJpegOffset = 0; - return; - } + if(!isLiveSnapshot()) { + if(mHalCamCtrl->mHdrMode == HDR_MODE && (hdrJpegCount%2) != 0){ + mStopCallbackLock.unlock( ); + mJpegOffset = 0; + return; + } + } if(!fail_cb_flag) { camera_memory_t *encodedMem = mHalCamCtrl->mGetMemory( mHalCamCtrl->mJpegMemory.fd[0], mJpegOffset, 1, mHalCamCtrl); @@ -363,9 +381,8 @@ receiveCompleteJpegPicture(jpeg_event_t event) ALOGE("%s: mGetMemory failed.\n", __func__); } memcpy(encodedMem->data, mHalCamCtrl->mJpegMemory.camera_memory[0]->data, mJpegOffset ); - mStopCallbackLock.unlock( ); - if ((mActive || isLiveSnapshot()) && jpg_data_cb != NULL) { + if ((mActive || isLiveSnapshot()) && jpg_data_cb != NULL && !mHalCamCtrl->mSnapCbDisabled) { ALOGV("%s: Calling upperlayer callback to store JPEG image", __func__); jpg_data_cb (msg_type,encodedMem, 0, NULL,mHalCamCtrl->mCallbackCookie); } @@ -373,8 +390,7 @@ receiveCompleteJpegPicture(jpeg_event_t event) jpg_data_cb = NULL; }else{ ALOGV("Image Encoding Failed... Notify Upper layer"); - mStopCallbackLock.unlock( ); - if((mActive || isLiveSnapshot()) && jpg_data_cb != NULL) { + if((mActive || isLiveSnapshot()) && jpg_data_cb != NULL && !mHalCamCtrl->mSnapCbDisabled) { jpg_data_cb (CAMERA_MSG_COMPRESSED_IMAGE,NULL, 0, NULL, mHalCamCtrl->mCallbackCookie); } @@ -387,7 +403,9 @@ receiveCompleteJpegPicture(jpeg_event_t event) } mHalCamCtrl->mStateLiveshot = false; - ALOGV("%s: X", __func__); + mStopCallbackLock.unlock( ); + ALOGI("%s After mStopCallbackLock.unlock()", __func__); + ALOGD("%s: X", __func__); } status_t QCameraStream_Snapshot:: @@ -1820,7 +1838,7 @@ void QCameraStream_Snapshot::notifyShutter(common_crop_t *crop, ALOGE("__debbug: Snapshot thread stopped \n"); return; } - if(mHalCamCtrl->mNotifyCb) + if(mHalCamCtrl->mNotifyCb && !mHalCamCtrl->mSnapCbDisabled) mHalCamCtrl->mNotifyCb(CAMERA_MSG_SHUTTER, 0, mPlayShutterSoundOnly, mHalCamCtrl->mCallbackCookie); ALOGV("%s: X", __func__); @@ -1905,8 +1923,13 @@ status_t QCameraStream_Snapshot::receiveRawPicture(mm_camera_ch_data_buf_t* recv camera_notify_callback notifyCb; camera_data_callback dataCb, jpgDataCb; - ALOGV("%s: E ", __func__); + ALOGD("%s: E ", __func__); + if(!mActive) { + ALOGD("%s: Stop receiving raw pic before acquiring lock", __func__); + return NO_ERROR; + } mStopCallbackLock.lock( ); + ALOGI("%s after mStopCallbackLock.lock()", __func__); if(!mActive) { mStopCallbackLock.unlock(); ALOGV("%s: Stop receiving raw pic ", __func__); @@ -1924,16 +1947,16 @@ status_t QCameraStream_Snapshot::receiveRawPicture(mm_camera_ch_data_buf_t* recv /* If it's raw snapshot, we just want to tell upperlayer to save the image*/ if(mSnapshotFormat == PICTURE_FORMAT_RAW) { - ALOGV("%s: Call notifyShutter 2nd time in case of RAW", __func__); - mStopCallbackLock.unlock(); + ALOGD("%s: Call notifyShutter 2nd time in case of RAW", __func__); + // mStopCallbackLock.unlock(); if(!mHalCamCtrl->mShutterSoundPlayed) { notifyShutter(&crop, true); } notifyShutter(&crop, false); mHalCamCtrl->mShutterSoundPlayed = false; - mStopCallbackLock.lock( ); - ALOGV("%s: Sending Raw Snapshot Callback to Upperlayer", __func__); + // mStopCallbackLock.lock( ); + ALOGD("%s: Sending Raw Snapshot Callback to Upperlayer", __func__); buf_index = recvd_frame->def.idx; if (mHalCamCtrl->mDataCb && mActive && @@ -1942,9 +1965,9 @@ status_t QCameraStream_Snapshot::receiveRawPicture(mm_camera_ch_data_buf_t* recv } else { dataCb = NULL; } - mStopCallbackLock.unlock(); + // mStopCallbackLock.unlock(); - if(dataCb) { + if(mActive && dataCb && !mHalCamCtrl->mSnapCbDisabled) { dataCb( CAMERA_MSG_COMPRESSED_IMAGE, mHalCamCtrl->mRawMemory.camera_memory[buf_index], 0, NULL, @@ -1952,6 +1975,7 @@ status_t QCameraStream_Snapshot::receiveRawPicture(mm_camera_ch_data_buf_t* recv } /* TBD: Temp: To be removed once event handling is enabled */ mm_app_snapshot_done(); + mStopCallbackLock.unlock(); } else { /*TBD: v4l2 doesn't have support to provide cropinfo along with frame. We'll need to query.*/ @@ -2052,7 +2076,12 @@ status_t QCameraStream_Snapshot::receiveRawPicture(mm_camera_ch_data_buf_t* recv notifyCb = NULL; } - mStopCallbackLock.unlock(); + mSnapshotDataCallingBack = 1; + if (!mActive) { + ALOGE("%s Snapshot thread is stoped, deinit buffer and exit", __func__); + goto end; + } + if(!mHalCamCtrl->mShutterSoundPlayed) { notifyShutter(&crop, true); } @@ -2060,10 +2089,13 @@ status_t QCameraStream_Snapshot::receiveRawPicture(mm_camera_ch_data_buf_t* recv mHalCamCtrl->mShutterSoundPlayed = false; if(mHalCamCtrl->mHdrMode == HDR_MODE) { - if ((hdrRawCount % 3) != 2) + if ((hdrRawCount % 3) != 2) { + mStopCallbackLock.unlock(); return NO_ERROR; - else + } + else { hdrRawCount++; + } } if (rc != NO_ERROR) @@ -2079,17 +2111,16 @@ status_t QCameraStream_Snapshot::receiveRawPicture(mm_camera_ch_data_buf_t* recv jpgDataCb = mHalCamCtrl->mDataCb; } else { jpgDataCb = NULL; - } + } ALOGE("%s: encode err so data cb", __func__); - //mStopCallbackLock.unlock(); - if (dataCb) { + if (mActive && dataCb && !mHalCamCtrl->mSnapCbDisabled) { dataCb(CAMERA_MSG_RAW_IMAGE, mHalCamCtrl->mSnapshotMemory.camera_memory[0], 1, NULL, mHalCamCtrl->mCallbackCookie); } - if (notifyCb) { + if (mActive && notifyCb && !mHalCamCtrl->mSnapCbDisabled) { notifyCb(CAMERA_MSG_RAW_IMAGE_NOTIFY, 0, 0, mHalCamCtrl->mCallbackCookie); } - if (jpgDataCb) { + if (mActive && jpgDataCb && !mHalCamCtrl->mSnapCbDisabled) { jpgDataCb(CAMERA_MSG_COMPRESSED_IMAGE, NULL, 0, NULL, mHalCamCtrl->mCallbackCookie); @@ -2099,13 +2130,12 @@ status_t QCameraStream_Snapshot::receiveRawPicture(mm_camera_ch_data_buf_t* recv free(frame); } } else { - - //mStopCallbackLock.unlock(); - if (dataCb) { + ALOGI("%s: NO Error while encoding/displaying/saving image", __func__); + if (mActive && dataCb && !mHalCamCtrl->mSnapCbDisabled) { dataCb(CAMERA_MSG_RAW_IMAGE, mHalCamCtrl->mSnapshotMemory.camera_memory[0], 1, NULL, mHalCamCtrl->mCallbackCookie); } - if (notifyCb) { + if (mActive && notifyCb && !mHalCamCtrl->mSnapCbDisabled) { notifyCb(CAMERA_MSG_RAW_IMAGE_NOTIFY, 0, 0, mHalCamCtrl->mCallbackCookie); } @@ -2118,6 +2148,14 @@ status_t QCameraStream_Snapshot::receiveRawPicture(mm_camera_ch_data_buf_t* recv } } } +end: mSnapshotDataCallingBack = 0; + if (mFreeSnapshotBufAfterDataCb) { + deInitBuffer(); + mFreeSnapshotBufAfterDataCb = 0; + } + ALOGI("%s before mStopCallbackLock.unlock()", __func__); + mStopCallbackLock.unlock(); + ALOGI("%s After mStopCallbackLock.unlock()", __func__); } ALOGV("%s: X", __func__); @@ -2329,6 +2367,9 @@ status_t QCameraStream_Snapshot::start(void) { ALOGV("%s: E", __func__); Mutex::Autolock lock(mStopCallbackLock); + mSnapshotDataCallingBack = 0; + mFreeSnapshotBufAfterDataCb = 0; + mHalCamCtrl->mSnapCbDisabled = false; /* Keep track of number of snapshots to take - in case of multiple snapshot/burst mode */ @@ -2456,36 +2497,47 @@ void QCameraStream_Snapshot::stop(void) ALOGV("%s: E", __func__); - if(isLiveSnapshot() && mHalCamCtrl->mStateLiveshot) { - if(getSnapshotState() == SNAPSHOT_STATE_JPEG_ENCODING) { - ALOGV("Destroy Liveshot Jpeg Instance"); - omxJpegAbort(); - } - mStopCallbackLock.lock(); - deInitBuffer(); - mHalCamCtrl->mStateLiveshot = false; - mStopCallbackLock.unlock(); - return; - } - - if(!mActive) { + if(!mActive && !isLiveSnapshot()) { ALOGV("%s: Not Active return now", __func__); return; } mActive = false; - mStopCallbackLock.lock(); + mHalCamCtrl->mSnapCbDisabled = true; + Mutex::Autolock lock(mStopCallbackLock); + + if(isLiveSnapshot()) { + if(mHalCamCtrl->mStateLiveshot) { + if(getSnapshotState() == SNAPSHOT_STATE_JPEG_ENCODING) { + ALOGI("Destroy Liveshot Jpeg Instance"); + omxJpegAbort(); + } + ALOGI("%s: De Intialized the JPEG buffers", __func__); + deInitBuffer(); + mHalCamCtrl->mStateLiveshot = false; + return; + } + else { + ALOGI("%s: JPEG buffers are de Intialized and just return", __func__); + return; + } + } if (getSnapshotState() != SNAPSHOT_STATE_UNINIT) { /* Stop polling for further frames */ stopPolling(); if(getSnapshotState() == SNAPSHOT_STATE_JPEG_ENCODING) { - mStopCallbackLock.unlock(); ALOGV("Destroy Jpeg Instance"); omxJpegAbort(); - mStopCallbackLock.lock(); + } /* Depending upon current state, we'll need to allocate-deallocate-deinit*/ - deInitBuffer(); + if (mSnapshotDataCallingBack) { + mFreeSnapshotBufAfterDataCb = 1; + } + else { + mFreeSnapshotBufAfterDataCb = 0; + deInitBuffer(); + } } if(mSnapshotFormat == PICTURE_FORMAT_RAW) { @@ -2519,7 +2571,6 @@ void QCameraStream_Snapshot::stop(void) omxJpegClose(); #endif mFullLiveshot = false; - mStopCallbackLock.unlock(); ALOGV("%s: X", __func__); } @@ -2595,6 +2646,10 @@ void QCameraStream_Snapshot::notifyWDenoiseEvent(cam_ctrl_status_t status, void ALOGV("%s: WDN Done status (%d) received",__func__,status); Mutex::Autolock lock(mStopCallbackLock); + if(!mActive) { + ALOGD("%s: Stop receiving raw pic ", __func__); + return; + } if (frame == NULL) { ALOGE("%s: cookie is returned NULL", __func__); } else { @@ -2634,7 +2689,7 @@ void QCameraStream_Snapshot::notifyWDenoiseEvent(cam_ctrl_status_t status, void // launch next WDN if there is more in WDN Queue lauchNextWDenoiseFromQueue(); - mStopCallbackLock.unlock(); + // mStopCallbackLock.unlock(); if (rc != NO_ERROR) { @@ -2643,14 +2698,14 @@ void QCameraStream_Snapshot::notifyWDenoiseEvent(cam_ctrl_status_t status, void cam_evt_buf_done(mCameraId, frame); } - if (dataCb) { + if (mActive && dataCb && !mHalCamCtrl->mSnapCbDisabled) { dataCb(CAMERA_MSG_RAW_IMAGE, mHalCamCtrl->mSnapshotMemory.camera_memory[0], 1, NULL, mHalCamCtrl->mCallbackCookie); } - if (notifyCb) { + if (mActive && notifyCb && !mHalCamCtrl->mSnapCbDisabled) { notifyCb(CAMERA_MSG_RAW_IMAGE_NOTIFY, 0, 0, mHalCamCtrl->mCallbackCookie); } - if (jpgDataCb) { + if (mActive && jpgDataCb && !mHalCamCtrl->mSnapCbDisabled) { jpgDataCb(CAMERA_MSG_COMPRESSED_IMAGE, NULL, 0, NULL, mHalCamCtrl->mCallbackCookie); @@ -2873,5 +2928,20 @@ void QCameraStream_Snapshot::notifyHdrEvent(cam_ctrl_status_t status, void * coo } } +void QCameraStream_Snapshot::setSnapJpegCbState(bool state) +{ + ALOGE("%s: mSnapJpegCbRunning=%d. ", __func__, mHalCamCtrl->mSnapJpegCbRunning); + mHalCamCtrl->mSnapJpegCbLock.lock(); + mHalCamCtrl->mSnapJpegCbRunning = state; + if(state==false) + mHalCamCtrl->mSnapJpegCbWait.signal(); + mHalCamCtrl->mSnapJpegCbLock.unlock(); +} + +bool QCameraStream_Snapshot::getSnapJpegCbState() +{ + return mHalCamCtrl->mSnapJpegCbRunning; +} + }; // namespace android diff --git a/camera/QCameraStream.h b/camera/QCameraStream.h old mode 100644 new mode 100755 index 294ed584..5724dbb3 --- a/camera/QCameraStream.h +++ b/camera/QCameraStream.h @@ -144,6 +144,9 @@ class QCameraStream { //: public virtual RefBase{ camera_mode_t myMode; mutable Mutex mStopCallbackLock; + mutable Mutex mPreviewFrameLock; + int mSnapshotDataCallingBack; + int mFreeSnapshotBufAfterDataCb; private: StreamQueue mBusyQueue; StreamQueue mFreeQueue; @@ -287,6 +290,8 @@ class QCameraStream_Snapshot : public QCameraStream { void resetSnapshotCounters(void ); void InitHdrInfoForSnapshot(bool HDR_on, int number_frames, int *exp ); void notifyHdrEvent(cam_ctrl_status_t status, void * cookie); + bool getSnapJpegCbState(void); + void setSnapJpegCbState(bool state); private: QCameraStream_Snapshot(int, camera_mode_t); diff --git a/camera/mm-camera-interface/mm_camera.c b/camera/mm-camera-interface/mm_camera.c index 6cfb9b23..145fdb29 100644 --- a/camera/mm-camera-interface/mm_camera.c +++ b/camera/mm-camera-interface/mm_camera.c @@ -1087,11 +1087,6 @@ int32_t mm_camera_close(mm_camera_obj_t *my_obj) MM_CAMERA_STATE_EVT_RELEASE, NULL); } - CDBG("%s : Close Threads in Cam Close",__func__); - for(i = 0; i < MM_CAMERA_CH_MAX; i++) { - mm_camera_poll_thread_release(my_obj,(mm_camera_channel_type_t)i); - } - mm_camera_poll_threads_deinit(my_obj); my_obj->op_mode = MM_CAMERA_OP_MODE_NOTUSED; if(my_obj->ctrl_fd > 0) { rc = close(my_obj->ctrl_fd); diff --git a/camera/mm-camera-interface/mm_camera_channel.c b/camera/mm-camera-interface/mm_camera_channel.c old mode 100644 new mode 100755 index 6e01c8da..40f3fb04 --- a/camera/mm-camera-interface/mm_camera_channel.c +++ b/camera/mm-camera-interface/mm_camera_channel.c @@ -443,7 +443,7 @@ static int32_t mm_camera_ch_util_qbuf(mm_camera_obj_t *my_obj, cache_frame = val->snapshot.main.frame; CDBG("buffer fd = %d, length = %d, vaddr = %p\n", val->snapshot.main.frame->fd, val->snapshot.main.frame->ion_alloc.len, val->snapshot.main.frame->buffer); - if(!rc) { + if(!rc && (!my_obj->full_liveshot)) { if (my_obj->op_mode == MM_CAMERA_OP_MODE_ZSL) stream = &my_obj->ch[MM_CAMERA_CH_PREVIEW].preview.stream; else diff --git a/camera/mm-camera-interface/mm_camera_interface2.c b/camera/mm-camera-interface/mm_camera_interface2.c old mode 100644 new mode 100755 index 433c612f..f6ccca93 --- a/camera/mm-camera-interface/mm_camera_interface2.c +++ b/camera/mm-camera-interface/mm_camera_interface2.c @@ -384,7 +384,7 @@ static void mm_camera_ops_close (mm_camera_t * camera) if(my_obj->ref_count > 0) { CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count); } else { - mm_camera_poll_thread_release(my_obj, MM_CAMERA_CH_MAX); + // mm_camera_poll_thread_release(my_obj, MM_CAMERA_CH_MAX); (void)mm_camera_close(g_cam_ctrl.cam_obj[camera_id]); pthread_mutex_destroy(&my_obj->mutex); free(my_obj); @@ -394,6 +394,25 @@ static void mm_camera_ops_close (mm_camera_t * camera) pthread_mutex_unlock(&g_mutex); } +static void mm_camera_ops_stop (mm_camera_t * camera) +{ + mm_camera_obj_t * my_obj; + int i; + int8_t camera_id = camera->camera_info.camera_id; + + pthread_mutex_lock(&g_mutex); + my_obj = g_cam_ctrl.cam_obj[camera_id]; + if(my_obj) { + CDBG("%s : Close Threads in mm_camera_ops_stop",__func__); + for(i = 0; i <= MM_CAMERA_CH_MAX; i++) { + mm_camera_poll_thread_release(my_obj,(mm_camera_channel_type_t)i); + } + mm_camera_poll_threads_deinit(my_obj); + } + pthread_mutex_unlock(&g_mutex); +} + + static int32_t mm_camera_ops_ch_acquire(mm_camera_t * camera, mm_camera_channel_type_t ch_type) { @@ -464,6 +483,7 @@ static mm_camera_ops_t mm_camera_ops = { .action = mm_camera_ops_action, .open = mm_camera_ops_open, .close = mm_camera_ops_close, + .stop = mm_camera_ops_stop, .ch_acquire = mm_camera_ops_ch_acquire, .ch_release = mm_camera_ops_ch_release, .ch_set_attr = mm_camera_ops_ch_attr, @@ -850,6 +870,14 @@ void cam_ops_close(int cam_id) } } +void cam_ops_stop(int cam_id) +{ + mm_camera_t * mm_cam = get_camera_by_id(cam_id); + if (mm_cam) { + mm_cam->ops->stop(mm_cam); + } +} + int32_t cam_ops_ch_acquire(int cam_id, mm_camera_channel_type_t ch_type) { int32_t rc = -1; diff --git a/camera/mm-camera-interface/mm_camera_interface2.h b/camera/mm-camera-interface/mm_camera_interface2.h old mode 100644 new mode 100755 index e674d79c..ba4dcd52 --- a/camera/mm-camera-interface/mm_camera_interface2.h +++ b/camera/mm-camera-interface/mm_camera_interface2.h @@ -295,6 +295,7 @@ typedef struct { mm_camera_ops_type_t opcode, void *val); int32_t (*open)(mm_camera_t * camera, mm_camera_op_mode_type_t op_mode); void (*close)(mm_camera_t * camera); + void (*stop)(mm_camera_t * camera); int32_t (*ch_acquire)(mm_camera_t * camera, mm_camera_channel_type_t ch_type); void (*ch_release)(mm_camera_t * camera, mm_camera_channel_type_t ch_type); int32_t (*ch_set_attr)(mm_camera_t * camera, mm_camera_channel_type_t ch_type, @@ -473,6 +474,7 @@ int32_t cam_ops_action(int cam_id, uint8_t start, mm_camera_ops_type_t opcode, void *val); int32_t cam_ops_open(int cam_id, mm_camera_op_mode_type_t op_mode); void cam_ops_close(int cam_id); +void cam_ops_stop(int cam_id); int32_t cam_ops_ch_acquire(int cam_id, mm_camera_channel_type_t ch_type); void cam_ops_ch_release(int cam_id, mm_camera_channel_type_t ch_type); int32_t cam_ops_ch_set_attr(int cam_id, mm_camera_channel_type_t ch_type,