| /* |
| ** |
| ** Copyright 2013, Samsung Electronics Co. LTD |
| ** |
| ** Licensed under the Apache License, Version 2.0 (the "License"); |
| ** you may not use this file except in compliance with the License. |
| ** You may obtain a copy of the License at |
| ** |
| ** http://www.apache.org/licenses/LICENSE-2.0 |
| ** |
| ** Unless required by applicable law or agreed to in writing, software |
| ** distributed under the License is distributed on an "AS IS" BASIS, |
| ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| ** See the License for the specific language governing permissions and |
| ** limitations under the License. |
| */ |
| |
| /* #define LOG_NDEBUG 0 */ |
| #define LOG_TAG "ExynosCamera" |
| #include <cutils/log.h> |
| |
| #include "ExynosCamera.h" |
| |
| #ifdef BURST_CAPTURE |
| #include <sys/resource.h> |
| #include <private/android_filesystem_config.h> |
| |
| #include <ctype.h> |
| #include <dirent.h> |
| #endif |
| |
| #ifdef LLS_CAPTURE |
| #define MULTI_FRAME_SHOT_PARAMETERS 0xF124 |
| #endif |
| |
| #ifdef FLASHED_LLS_CAPTURE |
| #define MULTI_FRAME_SHOT_FLASHED_INFO 0xF125 |
| #endif |
| #ifdef LLS_REPROCESSING |
| #define MULTI_FRAME_SHOT_BV_INFO 0xF127 |
| #endif |
| |
| #ifdef SR_CAPTURE |
| #define MULTI_FRAME_SHOT_SR_EXTRA_INFO 0xF126 |
| #endif |
| |
| #ifdef TOUCH_AE |
| #define AE_RESULT 0xF351 |
| #endif |
| |
| namespace android { |
| |
| /* vision */ |
| #ifdef VISION_DUMP |
| int dumpIndex = 0; |
| #endif |
| |
| #ifdef MONITOR_LOG_SYNC |
| uint32_t ExynosCamera::cameraSyncLogId = 0; |
| #endif |
| |
| ExynosCamera::ExynosCamera(int cameraId, __unused camera_device_t *dev) |
| { |
| ExynosCameraActivityUCTL *uctlMgr = NULL; |
| |
| BUILD_DATE(); |
| |
| checkAndroidVersion(); |
| |
| m_cameraId = cameraId; |
| m_use_companion = isCompanion(cameraId); |
| memset(m_name, 0x00, sizeof(m_name)); |
| |
| #ifdef SAMSUNG_COMPANION |
| m_companionNode = NULL; |
| m_companionThread = NULL; |
| CLOGI("INFO(%s):cameraId(%d), use_companion(%d)", __FUNCTION__, cameraId, m_use_companion); |
| |
| if(m_use_companion == true) { |
| m_companionThread = new mainCameraThread(this, &ExynosCamera::m_companionThreadFunc, |
| "companionshotThread", PRIORITY_URGENT_DISPLAY); |
| if (m_companionThread != NULL) { |
| m_companionThread->run(); |
| CLOGD("DEBUG(%s): companionThread starts", __FUNCTION__); |
| } else { |
| CLOGE("(%s):failed the m_companionThread.", __FUNCTION__); |
| } |
| } |
| #endif |
| |
| #if defined(SAMSUNG_EEPROM) |
| m_eepromThread = NULL; |
| if ((m_use_companion == false) && (isEEprom(getCameraId()) == true)) { |
| m_eepromThread = new mainCameraThread(this, &ExynosCamera::m_eepromThreadFunc, |
| "cameraeepromThread", PRIORITY_URGENT_DISPLAY); |
| if (m_eepromThread != NULL) { |
| m_eepromThread->run(); |
| CLOGD("DEBUG(%s): eepromThread starts", __FUNCTION__); |
| } else { |
| CLOGE("(%s): failed the m_eepromThread", __FUNCTION__); |
| } |
| } |
| #endif |
| |
| #ifdef SAMSUNG_COMPANION |
| m_exynosCameraParameters = new ExynosCameraParameters(m_cameraId, m_use_companion); |
| #else |
| m_exynosCameraParameters = new ExynosCameraParameters(m_cameraId); |
| #endif |
| m_cameraSensorId = getSensorId(m_cameraId); |
| CLOGD("DEBUG(%s):Parameters(CameraId=%d / m_cameraSensorId=%d) created", __FUNCTION__, m_cameraId, m_cameraSensorId); |
| |
| m_exynosCameraActivityControl = m_exynosCameraParameters->getActivityControl(); |
| |
| m_previewFrameFactory = NULL; |
| m_reprocessingFrameFactory = NULL; |
| /* vision */ |
| m_visionFrameFactory= NULL; |
| |
| m_ionAllocator = NULL; |
| m_grAllocator = NULL; |
| m_mhbAllocator = NULL; |
| |
| m_frameMgr = NULL; |
| |
| mIonClient = ion_open(); |
| if (mIonClient < 0) { |
| ALOGE("ERR(%s):mIonClient ion_open() fail", __func__); |
| mIonClient = -1; |
| } |
| |
| m_createInternalBufferManager(&m_bayerBufferMgr, "BAYER_BUF"); |
| m_createInternalBufferManager(&m_3aaBufferMgr, "3A1_BUF"); |
| m_createInternalBufferManager(&m_ispBufferMgr, "ISP_BUF"); |
| m_createInternalBufferManager(&m_hwDisBufferMgr, "HW_DIS_BUF"); |
| #ifdef SAMSUNG_DNG |
| m_createInternalBufferManager(&m_fliteBufferMgr, "FLITE_BUF"); |
| #endif |
| |
| /* reprocessing Buffer */ |
| m_createInternalBufferManager(&m_ispReprocessingBufferMgr, "ISP_RE_BUF"); |
| m_createInternalBufferManager(&m_sccReprocessingBufferMgr, "SCC_RE_BUF"); |
| |
| m_createInternalBufferManager(&m_sccBufferMgr, "SCC_BUF"); |
| m_createInternalBufferManager(&m_gscBufferMgr, "GSC_BUF"); |
| m_createInternalBufferManager(&m_jpegBufferMgr, "JPEG_BUF"); |
| #ifdef SUPPORT_SW_VDIS |
| m_createInternalBufferManager(&m_swVDIS_BufferMgr, "VDIS_BUF"); |
| #endif /*SUPPORT_SW_VDIS*/ |
| |
| m_createInternalBufferManager(&m_postPictureGscBufferMgr, "POSTPICTURE_GSC_BUF"); |
| #ifdef SAMSUNG_LBP |
| m_createInternalBufferManager(&m_lbpBufferMgr, "LBP_BUF"); |
| #endif |
| /* preview Buffer */ |
| m_scpBufferMgr = NULL; |
| m_createInternalBufferManager(&m_previewCallbackBufferMgr, "PREVIEW_CB_BUF"); |
| m_createInternalBufferManager(&m_highResolutionCallbackBufferMgr, "HIGH_RESOLUTION_CB_BUF"); |
| m_fdCallbackHeap = NULL; |
| #ifdef SR_CAPTURE |
| m_srCallbackHeap = NULL; |
| memset(m_faces_sr, 0, sizeof(camera_face_t) * NUM_OF_DETECTED_FACES); |
| #endif |
| |
| /* recording Buffer */ |
| m_recordingCallbackHeap = NULL; |
| m_createInternalBufferManager(&m_recordingBufferMgr, "REC_BUF"); |
| |
| /* highspeed dzoom Buffer Mgr */ |
| m_createInternalBufferManager(&m_zoomScalerBufferMgr, "DZOOM_SCALER_BUF"); |
| |
| m_createThreads(); |
| |
| m_createInternalBufferManager(&m_thumbnailGscBufferMgr, "THUMBNAIL_GSC_BUF"); |
| m_ThumbnailPostCallbackQ = new frame_queue_t; |
| m_ThumbnailPostCallbackQ->setWaitTime(2000000000); |
| |
| m_pipeFrameDoneQ = new frame_queue_t; |
| dstIspReprocessingQ = new frame_queue_t; |
| dstSccReprocessingQ = new frame_queue_t; |
| dstGscReprocessingQ = new frame_queue_t; |
| m_zoomPreviwWithCscQ = new frame_queue_t; |
| |
| dstPostPictureGscQ = new frame_queue_t; |
| dstPostPictureGscQ->setWaitTime(2000000000); |
| |
| dstJpegReprocessingQ = new frame_queue_t; |
| /* vision */ |
| m_pipeFrameVisionDoneQ = new frame_queue_t; |
| |
| m_frameFactoryQ = new framefactory_queue_t; |
| m_facedetectQ = new frame_queue_t; |
| m_facedetectQ->setWaitTime(500000000); |
| |
| m_autoFocusContinousQ.setWaitTime(550000000); |
| m_pipeFrameDoneQ->setWaitTime(550000000); |
| |
| m_previewQ = new frame_queue_t; |
| m_previewQ->setWaitTime(500000000); |
| m_previewCallbackGscFrameDoneQ = new frame_queue_t; |
| m_recordingQ = new frame_queue_t; |
| m_recordingQ->setWaitTime(500000000); |
| m_postPictureQ = new frame_queue_t(m_postPictureThread); |
| #ifdef SAMSUNG_DEBLUR |
| m_deblurCaptureQ = new frame_queue_t(m_deblurCaptureThread); |
| #endif |
| for(int i = 0 ; i < MAX_NUM_PIPES ; i++ ) { |
| m_mainSetupQ[i] = new frame_queue_t; |
| m_mainSetupQ[i]->setWaitTime(550000000); |
| } |
| m_jpegCallbackQ = new jpeg_callback_queue_t; |
| m_postviewCallbackQ = new postview_callback_queue_t; |
| m_thumbnailCallbackQ = new thumbnail_callback_queue_t; |
| #ifdef SAMSUNG_DEBLUR |
| m_detectDeblurCaptureQ = new deblur_capture_queue_t; |
| #endif |
| #ifdef SAMSUNG_LLS_DEBLUR |
| m_LDCaptureQ = new frame_queue_t(m_LDCaptureThread); |
| #endif |
| #ifdef SAMSUNG_LBP |
| m_LBPbufferQ = new lbp_queue_t; |
| #endif |
| #ifdef SAMSUNG_DNG |
| m_dngCaptureQ = new dng_capture_queue_t; |
| #endif |
| #ifdef SAMSUNG_BD |
| m_BDbufferQ = new bd_queue_t; |
| #endif |
| for (int threadNum = JPEG_SAVE_THREAD0; threadNum < JPEG_SAVE_THREAD_MAX_COUNT; threadNum++) { |
| m_jpegSaveQ[threadNum] = new jpeg_callback_queue_t; |
| m_jpegSaveQ[threadNum]->setWaitTime(2000000000); |
| m_burst[threadNum] = false; |
| m_running[threadNum] = false; |
| } |
| |
| dstIspReprocessingQ->setWaitTime(20000000); |
| dstSccReprocessingQ->setWaitTime(50000000); |
| dstGscReprocessingQ->setWaitTime(500000000); |
| dstJpegReprocessingQ->setWaitTime(500000000); |
| /* vision */ |
| m_pipeFrameVisionDoneQ->setWaitTime(2000000000); |
| |
| m_jpegCallbackQ->setWaitTime(1000000000); |
| #ifdef SAMSUNG_LLS_DEBLUR |
| m_postviewCallbackQ->setWaitTime(2000000000); |
| #else |
| m_postviewCallbackQ->setWaitTime(1000000000); |
| #endif |
| m_thumbnailCallbackQ->setWaitTime(1000000000); |
| #ifdef SAMSUNG_DEBLUR |
| m_detectDeblurCaptureQ->setWaitTime(1000000000); |
| #endif |
| #ifdef SAMSUNG_LBP |
| m_LBPbufferQ->setWaitTime(1000000000); //1sec |
| #endif |
| #ifdef SAMSUNG_DNG |
| m_dngCaptureQ->setWaitTime(1000000000); |
| #endif |
| #ifdef SAMSUNG_BD |
| m_BDbufferQ->setWaitTime(1000000000); //1sec |
| #endif |
| memset(&m_frameMetadata, 0, sizeof(camera_frame_metadata_t)); |
| memset(m_faces, 0, sizeof(camera_face_t) * NUM_OF_DETECTED_FACES); |
| |
| m_exitAutoFocusThread = false; |
| m_autoFocusRunning = false; |
| m_previewEnabled = false; |
| m_pictureEnabled = false; |
| m_recordingEnabled = false; |
| m_zslPictureEnabled = false; |
| m_flagStartFaceDetection = false; |
| m_flagLLSStart = false; |
| m_flagLightCondition = false; |
| #ifdef SAMSUNG_CAMERA_EXTRA_INFO |
| m_flagFlashCallback = false; |
| m_flagHdrCallback = false; |
| #endif |
| m_fdThreshold = 0; |
| m_captureSelector = NULL; |
| m_sccCaptureSelector = NULL; |
| m_autoFocusType = 0; |
| m_hdrEnabled = false; |
| m_doCscRecording = true; |
| m_recordingBufferCount = NUM_RECORDING_BUFFERS; |
| m_frameSkipCount = 0; |
| m_isZSLCaptureOn = false; |
| m_isSuccessedBufferAllocation = false; |
| #ifdef BURST_CAPTURE |
| m_burstCaptureCallbackCount = 0; |
| m_burstShutterLocation = BURST_SHUTTER_PREPICTURE; |
| #endif |
| m_skipCount = 0; |
| |
| #ifdef SAMSUNG_LLV |
| #ifdef SAMSUNG_LLV_TUNING |
| m_LLVpowerLevel = UNI_PLUGIN_POWER_CONTROL_OFF; |
| m_checkLLVtuning(); |
| #endif |
| m_LLVstatus = LLV_UNINIT; |
| m_LLVpluginHandle = uni_plugin_load(LLV_PLUGIN_NAME); |
| if(m_LLVpluginHandle == NULL) { |
| CLOGE("[LLV](%s[%d]): LLV plugin load failed!!", __FUNCTION__, __LINE__); |
| } |
| #endif |
| |
| #ifdef SAMSUNG_OT |
| m_OTstatus = UNI_PLUGIN_OBJECT_TRACKING_IDLE; |
| m_OTstart = OBJECT_TRACKING_IDLE; |
| m_OTisTouchAreaGet = false; |
| m_OTisWait = false; |
| m_OTpluginHandle = uni_plugin_load(OBJECT_TRACKING_PLUGIN_NAME); |
| if(m_OTpluginHandle == NULL) { |
| CLOGE("[OBTR](%s[%d]): Object Tracking plugin load failed!!", __FUNCTION__, __LINE__); |
| } |
| #endif |
| |
| #ifdef SAMSUNG_LBP |
| m_LBPindex = 0; |
| m_LBPCount = 0; |
| m_isLBPlux = false; |
| m_isLBPon = false; |
| m_LBPpluginHandle = uni_plugin_load(BESTPHOTO_PLUGIN_NAME); |
| if(m_LBPpluginHandle == NULL) { |
| CLOGE("[LBP](%s[%d]):Bestphoto plugin load failed!!", __FUNCTION__, __LINE__); |
| } |
| #endif |
| |
| #ifdef SAMSUNG_JQ |
| m_isJpegQtableOn = false; |
| m_JQpluginHandle = uni_plugin_load(JPEG_QTABLE_PLUGIN_NAME); |
| if(m_JQpluginHandle == NULL) { |
| CLOGE("[JQ](%s[%d]):JpegQtable plugin load failed!!", __FUNCTION__, __LINE__); |
| } |
| #endif |
| |
| #ifdef SAMSUNG_BD |
| m_BDpluginHandle = uni_plugin_load(BLUR_DETECTION_PLUGIN_NAME); |
| if(m_BDpluginHandle == NULL) { |
| CLOGE("[BD](%s[%d]):BlurDetection plugin load failed!!", __FUNCTION__, __LINE__); |
| } |
| m_BDstatus = BLUR_DETECTION_IDLE; |
| #endif |
| |
| #ifdef SAMSUNG_DEBLUR |
| m_DeblurpluginHandle = uni_plugin_load(DEBLUR_PLUGIN_NAME); |
| if(m_DeblurpluginHandle == NULL) { |
| CLOGE("[Deblur](%s[%d]):Deblur plugin load failed!!", __FUNCTION__, __LINE__); |
| } |
| #endif |
| |
| #ifdef SAMSUNG_LLS_DEBLUR |
| m_LLSpluginHandle = uni_plugin_load(LLS_PLUGIN_NAME); |
| if(m_LLSpluginHandle == NULL) { |
| CLOGE("[LDC](%s[%d]):LLS plugin load failed!!", __FUNCTION__, __LINE__); |
| } |
| #endif |
| |
| #ifdef SAMSUNG_HLV |
| m_HLV = NULL; |
| m_HLVprocessStep = HLV_PROCESS_DONE; |
| #endif |
| |
| #ifdef SAMSUNG_DOF |
| m_lensmoveCount = 0; |
| m_AFstatus = ExynosCameraActivityAutofocus::AUTOFOCUS_STATE_NONE; |
| m_currentSetStart = false; |
| m_flagMetaDataSet = false; |
| #endif |
| #ifdef FPS_CHECK |
| for (int i = 0; i < DEBUG_MAX_PIPE_NUM; i++) |
| m_debugFpsCount[i] = 0; |
| #endif |
| |
| m_stopBurstShot = false; |
| m_disablePreviewCB = false; |
| m_checkFirstFrameLux = false; |
| |
| #ifdef LLS_CAPTURE |
| for (int i = 0; i < LLS_HISTORY_COUNT; i++) |
| m_needLLS_history[i] = 0; |
| #endif |
| m_callbackState = 0; |
| m_callbackStateOld = 0; |
| m_callbackMonitorCount = 0; |
| |
| m_highResolutionCallbackRunning = false; |
| m_highResolutionCallbackQ = new frame_queue_t(m_highResolutionCallbackThread); |
| m_highResolutionCallbackQ->setWaitTime(500000000); |
| m_skipReprocessing = false; |
| m_isFirstStart = true; |
| m_exynosCameraParameters->setIsFirstStartFlag(m_isFirstStart); |
| |
| #ifdef RAWDUMP_CAPTURE |
| m_RawCaptureDumpQ = new frame_queue_t(m_RawCaptureDumpThread); |
| #endif |
| |
| #ifdef SAMSUNG_MAGICSHOT |
| if(getCameraId() == CAMERA_ID_BACK) { |
| m_magicshotMaxCount = MAGICSHOT_COUNT_REAR; |
| } else { |
| m_magicshotMaxCount = MAGICSHOT_COUNT_FRONT; |
| } |
| #endif |
| |
| #ifdef OIS_CAPTURE |
| ExynosCameraActivitySpecialCapture *m_sCaptureMgr = m_exynosCameraActivityControl->getSpecialCaptureMgr(); |
| m_sCaptureMgr->resetOISCaptureFcount(); |
| |
| m_OISCaptureShutterEnabled = false; |
| #endif |
| |
| #ifdef RAWDUMP_CAPTURE |
| ExynosCameraActivitySpecialCapture *m_sCapture = m_exynosCameraActivityControl->getSpecialCaptureMgr(); |
| m_sCapture->resetRawCaptureFcount(); |
| #endif |
| |
| #ifdef SAMSUNG_LLS_DEBLUR |
| m_LDCaptureCount = 0; |
| |
| for (int i = 0; i < MAX_LD_CAPTURE_COUNT; i++) { |
| m_LDBufIndex[i] = 0; |
| } |
| #endif |
| |
| m_exynosconfig = NULL; |
| m_setConfigInform(); |
| |
| m_setFrameManager(); |
| |
| |
| /* HACK Reset Preview Flag*/ |
| m_resetPreview = false; |
| |
| m_dynamicSccCount = 0; |
| m_previewBufferCount = NUM_PREVIEW_BUFFERS; |
| |
| #ifdef FIRST_PREVIEW_TIME_CHECK |
| m_flagFirstPreviewTimerOn = false; |
| #endif |
| |
| /* init infomation of fd orientation*/ |
| m_exynosCameraParameters->setDeviceOrientation(0); |
| uctlMgr = m_exynosCameraActivityControl->getUCTLMgr(); |
| if (uctlMgr != NULL) |
| uctlMgr->setDeviceRotation(m_exynosCameraParameters->getFdOrientation()); |
| #ifdef MONITOR_LOG_SYNC |
| m_syncLogDuration = 0; |
| #endif |
| #ifdef SAMSUNG_LBP |
| if(getCameraId() == CAMERA_ID_FRONT) { |
| m_exynosCameraParameters->resetNormalBestFrameCount(); |
| m_exynosCameraParameters->resetSCPFrameCount(); |
| m_exynosCameraParameters->resetBayerFrameCount(); |
| } |
| #endif |
| #ifdef SAMSUNG_HRM |
| m_uv_rayHandle = NULL; |
| #endif |
| #ifdef SAMSUNG_LIGHT_IR |
| m_light_irHandle = NULL; |
| #endif |
| #ifdef SAMSUNG_GYRO |
| m_gyroHandle = NULL; |
| #endif |
| |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| /* init one second burst capture parameters. */ |
| for (int i = 0; i < ONE_SECOND_BURST_CAPTURE_CHECK_COUNT; i++) |
| TakepictureDurationTime[i] = 0; |
| m_one_second_burst_capture = false; |
| m_one_second_burst_first_after_open = false; |
| m_one_second_jpegCallbackHeap = NULL; |
| m_one_second_postviewCallbackHeap = NULL; |
| #endif |
| m_initFrameFactory(); |
| #ifdef SAMSUNG_QUICKSHOT |
| m_quickShotStart = true; |
| #endif |
| |
| m_tempshot = new struct camera2_shot_ext; |
| m_fdmeta_shot = new struct camera2_shot_ext; |
| m_meta_shot = new struct camera2_shot_ext; |
| |
| #ifdef SUPPORT_SW_VDIS |
| m_swVDIS_fd_dm = new struct camera2_dm; |
| m_swVDIS_FaceData = new struct swVDIS_FaceData; |
| #endif /*SUPPORT_SW_VDIS*/ |
| |
| #ifdef USE_CAMERA_PREVIEW_FRAME_SCHEDULER |
| m_previewFrameScheduler = new SecCameraPreviewFrameScheduler(); |
| #endif |
| |
| #ifdef CAMERA_FAST_ENTRANCE_V1 |
| m_fastEntrance = false; |
| m_isFirstParametersSet = false; |
| #endif |
| |
| #ifdef SAMSUNG_DNG |
| m_searchDNGFrame = false; |
| m_dngFrameNumber = 0; |
| m_longExposureEnds = true; |
| m_dngLongExposureRemainCount = 0; |
| m_dngFrameNumberForManualExposure = 0; |
| #endif |
| m_longExposureRemainCount = 0; |
| m_longExposurePreview = false; |
| m_stopLongExposure = false; |
| m_cancelPicture = false; |
| |
| #ifdef SAMSUNG_DEBLUR |
| m_useDeblurCaptureOn = false; |
| m_deblurCaptureCount = 0; |
| #endif |
| m_previewWindow = NULL; |
| } |
| |
| status_t ExynosCamera::m_setConfigInform() { |
| struct ExynosConfigInfo exynosConfig; |
| memset((void *)&exynosConfig, 0x00, sizeof(exynosConfig)); |
| |
| exynosConfig.mode = CONFIG_MODE::NORMAL; |
| |
| exynosConfig.info[CONFIG_MODE::NORMAL].bufInfo.num_bayer_buffers = (getCameraId() == CAMERA_ID_BACK) ? NUM_BAYER_BUFFERS : FRONT_NUM_BAYER_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::NORMAL].bufInfo.init_bayer_buffers = INIT_BAYER_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::NORMAL].bufInfo.num_3aa_buffers = (getCameraId() == CAMERA_ID_BACK) ? NUM_3AA_BUFFERS : FRONT_NUM_3AA_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::NORMAL].bufInfo.num_hwdis_buffers = NUM_HW_DIS_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::NORMAL].bufInfo.num_preview_buffers = NUM_PREVIEW_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::NORMAL].bufInfo.num_picture_buffers = (getCameraId() == CAMERA_ID_BACK) ? NUM_PICTURE_BUFFERS : FRONT_NUM_PICTURE_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::NORMAL].bufInfo.num_reprocessing_buffers = NUM_REPROCESSING_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::NORMAL].bufInfo.num_recording_buffers = NUM_RECORDING_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::NORMAL].bufInfo.num_fastaestable_buffer = INITIAL_SKIP_FRAME; |
| exynosConfig.info[CONFIG_MODE::NORMAL].bufInfo.reprocessing_bayer_hold_count = REPROCESSING_BAYER_HOLD_COUNT; |
| exynosConfig.info[CONFIG_MODE::NORMAL].bufInfo.preview_buffer_margin = NUM_PREVIEW_BUFFERS_MARGIN; |
| |
| exynosConfig.info[CONFIG_MODE::NORMAL].pipeInfo.prepare[PIPE_FLITE] = (getCameraId() == CAMERA_ID_BACK) ? PIPE_FLITE_PREPARE_COUNT : PIPE_FLITE_FRONT_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::NORMAL].pipeInfo.prepare[PIPE_3AC] = PIPE_3AC_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::NORMAL].pipeInfo.prepare[PIPE_3AA] = PIPE_3AA_ISP_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::NORMAL].pipeInfo.prepare[PIPE_3AA_ISP] = PIPE_3AA_ISP_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::NORMAL].pipeInfo.prepare[PIPE_ISP] = PIPE_ISP_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::NORMAL].pipeInfo.prepare[PIPE_ISPC] = (getCameraId() == CAMERA_ID_BACK) ? PIPE_3AA_ISP_PREPARE_COUNT : PIPE_FLITE_FRONT_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::NORMAL].pipeInfo.prepare[PIPE_SCC] = (getCameraId() == CAMERA_ID_BACK) ? PIPE_3AA_ISP_PREPARE_COUNT : PIPE_FLITE_FRONT_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::NORMAL].pipeInfo.prepare[PIPE_SCP] = (getCameraId() == CAMERA_ID_BACK) ? PIPE_SCP_PREPARE_COUNT : PIPE_SCP_FRONT_PREPARE_COUNT; |
| |
| /* reprocessing */ |
| exynosConfig.info[CONFIG_MODE::NORMAL].pipeInfo.prepare[PIPE_SCP_REPROCESSING] = PIPE_SCP_REPROCESSING_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::NORMAL].pipeInfo.prepare[PIPE_ISPC_REPROCESSING] = PIPE_SCC_REPROCESSING_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::NORMAL].pipeInfo.prepare[PIPE_SCC_REPROCESSING] = PIPE_SCC_REPROCESSING_PREPARE_COUNT; |
| |
| #if (USE_HIGHSPEED_RECORDING) |
| /* Config HIGH_SPEED 60 buffer & pipe info */ |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_60].bufInfo.num_bayer_buffers = (getCameraId() == CAMERA_ID_BACK) ? FPS60_NUM_NUM_BAYER_BUFFERS : FPS60_FRONT_NUM_BAYER_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_60].bufInfo.init_bayer_buffers = FPS60_NUM_NUM_BAYER_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_60].bufInfo.num_3aa_buffers = FPS60_NUM_NUM_BAYER_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_60].bufInfo.num_hwdis_buffers = FPS60_NUM_HW_DIS_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_60].bufInfo.num_preview_buffers = FPS60_NUM_PREVIEW_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_60].bufInfo.num_picture_buffers = (getCameraId() == CAMERA_ID_BACK) ? FPS60_NUM_PICTURE_BUFFERS : FPS60_FRONT_NUM_PICTURE_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_60].bufInfo.num_reprocessing_buffers = FPS60_NUM_REPROCESSING_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_60].bufInfo.num_recording_buffers = FPS60_NUM_RECORDING_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_60].bufInfo.num_fastaestable_buffer = FPS60_INITIAL_SKIP_FRAME; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_60].bufInfo.reprocessing_bayer_hold_count = FPS60_REPROCESSING_BAYER_HOLD_COUNT; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_60].bufInfo.preview_buffer_margin = FPS60_NUM_PREVIEW_BUFFERS_MARGIN; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_60].pipeInfo.prepare[PIPE_FLITE] = FPS60_PIPE_FLITE_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_60].pipeInfo.prepare[PIPE_3AC] = FPS60_PIPE_3AC_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_60].pipeInfo.prepare[PIPE_3AA] = FPS60_PIPE_3AA_ISP_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_60].pipeInfo.prepare[PIPE_3AA_ISP] = FPS60_PIPE_3AA_ISP_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_60].pipeInfo.prepare[PIPE_SCP] = FPS60_PIPE_SCP_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_60].pipeInfo.prepare[PIPE_SCP_REPROCESSING] = FPS60_PIPE_SCP_REPROCESSING_PREPARE_COUNT; |
| |
| /* Config HIGH_SPEED 120 buffer & pipe info */ |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_120].bufInfo.num_bayer_buffers = (getCameraId() == CAMERA_ID_BACK) ? FPS120_NUM_NUM_BAYER_BUFFERS : FPS120_FRONT_NUM_BAYER_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_120].bufInfo.init_bayer_buffers = FPS120_NUM_NUM_BAYER_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_120].bufInfo.num_3aa_buffers = FPS120_NUM_NUM_BAYER_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_120].bufInfo.num_hwdis_buffers = FPS120_NUM_HW_DIS_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_120].bufInfo.num_preview_buffers = FPS120_NUM_PREVIEW_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_120].bufInfo.num_picture_buffers = (getCameraId() == CAMERA_ID_BACK) ? FPS120_NUM_PICTURE_BUFFERS : FPS120_FRONT_NUM_PICTURE_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_120].bufInfo.num_reprocessing_buffers = FPS120_NUM_REPROCESSING_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_120].bufInfo.num_recording_buffers = FPS120_NUM_RECORDING_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_120].bufInfo.num_fastaestable_buffer = FPS120_INITIAL_SKIP_FRAME; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_120].bufInfo.reprocessing_bayer_hold_count = FPS120_REPROCESSING_BAYER_HOLD_COUNT; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_120].bufInfo.preview_buffer_margin = FPS120_NUM_PREVIEW_BUFFERS_MARGIN; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_120].pipeInfo.prepare[PIPE_FLITE] = FPS120_PIPE_FLITE_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_120].pipeInfo.prepare[PIPE_3AC] = FPS120_PIPE_3AC_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_120].pipeInfo.prepare[PIPE_3AA] = FPS120_PIPE_3AA_ISP_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_120].pipeInfo.prepare[PIPE_3AA_ISP] = FPS120_PIPE_3AA_ISP_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_120].pipeInfo.prepare[PIPE_SCP] = FPS120_PIPE_SCP_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_120].pipeInfo.prepare[PIPE_SCP_REPROCESSING] = FPS120_PIPE_SCP_REPROCESSING_PREPARE_COUNT; |
| |
| /* Config HIGH_SPEED 240 buffer & pipe info */ |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_240].bufInfo.num_bayer_buffers = (getCameraId() == CAMERA_ID_BACK) ? FPS240_NUM_NUM_BAYER_BUFFERS : FPS240_FRONT_NUM_BAYER_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_240].bufInfo.init_bayer_buffers = FPS240_INIT_BAYER_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_240].bufInfo.num_3aa_buffers = FPS240_NUM_NUM_BAYER_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_240].bufInfo.num_hwdis_buffers = FPS240_NUM_HW_DIS_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_240].bufInfo.num_preview_buffers = FPS240_NUM_PREVIEW_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_240].bufInfo.num_picture_buffers = (getCameraId() == CAMERA_ID_BACK) ? FPS240_NUM_PICTURE_BUFFERS : FPS240_FRONT_NUM_PICTURE_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_240].bufInfo.num_reprocessing_buffers = FPS240_NUM_REPROCESSING_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_240].bufInfo.num_recording_buffers = FPS240_NUM_RECORDING_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_240].bufInfo.num_fastaestable_buffer = FPS240_INITIAL_SKIP_FRAME; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_240].bufInfo.reprocessing_bayer_hold_count = FPS240_REPROCESSING_BAYER_HOLD_COUNT; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_240].bufInfo.preview_buffer_margin = FPS240_NUM_PREVIEW_BUFFERS_MARGIN; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_240].pipeInfo.prepare[PIPE_FLITE] = FPS240_PIPE_FLITE_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_240].pipeInfo.prepare[PIPE_3AC] = FPS240_PIPE_3AC_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_240].pipeInfo.prepare[PIPE_3AA] = FPS240_PIPE_3AA_ISP_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_240].pipeInfo.prepare[PIPE_3AA_ISP] = FPS240_PIPE_3AA_ISP_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_240].pipeInfo.prepare[PIPE_SCP] = FPS240_PIPE_SCP_PREPARE_COUNT; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_240].pipeInfo.prepare[PIPE_SCP_REPROCESSING] = FPS240_PIPE_SCP_REPROCESSING_PREPARE_COUNT; |
| #endif |
| |
| m_exynosCameraParameters->setConfig(&exynosConfig); |
| |
| m_exynosconfig = m_exynosCameraParameters->getConfig(); |
| |
| return NO_ERROR; |
| } |
| |
| void ExynosCamera::m_createThreads(void) |
| { |
| m_mainThread = new mainCameraThread(this, &ExynosCamera::m_mainThreadFunc, "ExynosCameraThread", PRIORITY_URGENT_DISPLAY); |
| CLOGD("DEBUG(%s):mainThread created", __FUNCTION__); |
| |
| m_previewThread = new mainCameraThread(this, &ExynosCamera::m_previewThreadFunc, "previewThread", PRIORITY_DISPLAY); |
| CLOGD("DEBUG(%s):previewThread created", __FUNCTION__); |
| |
| /* |
| * In here, we cannot know single, dual scenario. |
| * So, make all threads. |
| */ |
| /* if (m_exynosCameraParameters->isFlite3aaOtf() == true) { */ |
| if (1) { |
| m_mainSetupQThread[INDEX(PIPE_FLITE)] = new mainCameraThread(this, &ExynosCamera::m_mainThreadQSetupFLITE, "mainThreadQSetupFLITE", PRIORITY_URGENT_DISPLAY); |
| CLOGD("DEBUG(%s):mainThreadQSetupFLITEThread created", __FUNCTION__); |
| |
| /* Change 3AA_ISP, 3AC, SCP to ISP */ |
| /* |
| m_mainSetupQThread[INDEX(PIPE_3AC)] = new mainCameraThread(this, &ExynosCamera::m_mainThreadQSetup3AC, "mainThreadQSetup3AC", PRIORITY_URGENT_DISPLAY); |
| CLOGD("DEBUG(%s):mainThreadQSetup3ACThread created", __FUNCTION__); |
| |
| m_mainSetupQThread[INDEX(PIPE_3AA_ISP)] = new mainCameraThread(this, &ExynosCamera::m_mainThreadQSetup3AA_ISP, "mainThreadQSetup3AA_ISP", PRIORITY_URGENT_DISPLAY); |
| CLOGD("DEBUG(%s):mainThreadQSetup3AA_ISPThread created", __FUNCTION__); |
| |
| m_mainSetupQThread[INDEX(PIPE_ISP)] = new mainCameraThread(this, &ExynosCamera::m_mainThreadQSetupISP, "mainThreadQSetupISP", PRIORITY_URGENT_DISPLAY); |
| CLOGD("DEBUG(%s):mainThreadQSetupISPThread created", __FUNCTION__); |
| |
| m_mainSetupQThread[INDEX(PIPE_SCP)] = new mainCameraThread(this, &ExynosCamera::m_mainThreadQSetupSCP, "mainThreadQSetupSCP", PRIORITY_URGENT_DISPLAY); |
| CLOGD("DEBUG(%s):mainThreadQSetupSCPThread created", __FUNCTION__); |
| */ |
| |
| m_mainSetupQThread[INDEX(PIPE_3AA)] = new mainCameraThread(this, &ExynosCamera::m_mainThreadQSetup3AA, "mainThreadQSetup3AA", PRIORITY_URGENT_DISPLAY); |
| CLOGD("DEBUG(%s):mainThreadQSetup3AAThread created", __FUNCTION__); |
| |
| } |
| m_setBuffersThread = new mainCameraThread(this, &ExynosCamera::m_setBuffersThreadFunc, "setBuffersThread"); |
| CLOGD("DEBUG(%s):setBuffersThread created", __FUNCTION__); |
| |
| m_startPictureInternalThread = new mainCameraThread(this, &ExynosCamera::m_startPictureInternalThreadFunc, "startPictureInternalThread"); |
| CLOGD("DEBUG(%s):startPictureInternalThread created", __FUNCTION__); |
| |
| m_startPictureBufferThread = new mainCameraThread(this, &ExynosCamera::m_startPictureBufferThreadFunc, "startPictureBufferThread"); |
| CLOGD("DEBUG(%s):startPictureBufferThread created", __FUNCTION__); |
| |
| m_prePictureThread = new mainCameraThread(this, &ExynosCamera::m_prePictureThreadFunc, "prePictureThread"); |
| CLOGD("DEBUG(%s):prePictureThread created", __FUNCTION__); |
| |
| m_pictureThread = new mainCameraThread(this, &ExynosCamera::m_pictureThreadFunc, "PictureThread"); |
| CLOGD("DEBUG(%s):pictureThread created", __FUNCTION__); |
| |
| m_postPictureThread = new mainCameraThread(this, &ExynosCamera::m_postPictureThreadFunc, "postPictureThread"); |
| CLOGD("DEBUG(%s):postPictureThread created", __FUNCTION__); |
| |
| m_recordingThread = new mainCameraThread(this, &ExynosCamera::m_recordingThreadFunc, "recordingThread"); |
| CLOGD("DEBUG(%s):recordingThread created", __FUNCTION__); |
| |
| m_autoFocusThread = new mainCameraThread(this, &ExynosCamera::m_autoFocusThreadFunc, "AutoFocusThread"); |
| CLOGD("DEBUG(%s):autoFocusThread created", __FUNCTION__); |
| |
| m_autoFocusContinousThread = new mainCameraThread(this, &ExynosCamera::m_autoFocusContinousThreadFunc, "AutoFocusContinousThread"); |
| CLOGD("DEBUG(%s):autoFocusContinousThread created", __FUNCTION__); |
| |
| m_facedetectThread = new mainCameraThread(this, &ExynosCamera::m_facedetectThreadFunc, "FaceDetectThread"); |
| CLOGD("DEBUG(%s):FaceDetectThread created", __FUNCTION__); |
| |
| m_monitorThread = new mainCameraThread(this, &ExynosCamera::m_monitorThreadFunc, "monitorThread"); |
| CLOGD("DEBUG(%s):monitorThread created", __FUNCTION__); |
| |
| m_framefactoryThread = new mainCameraThread(this, &ExynosCamera::m_frameFactoryInitThreadFunc, "FrameFactoryInitThread"); |
| CLOGD("DEBUG(%s):FrameFactoryInitThread created", __FUNCTION__); |
| |
| m_jpegCallbackThread = new mainCameraThread(this, &ExynosCamera::m_jpegCallbackThreadFunc, "jpegCallbackThread"); |
| CLOGD("DEBUG(%s):jpegCallbackThread created", __FUNCTION__); |
| |
| m_zoomPreviwWithCscThread = new mainCameraThread(this, &ExynosCamera::m_zoomPreviwWithCscThreadFunc, "zoomPreviwWithCscQThread"); |
| CLOGD("DEBUG(%s):zoomPreviwWithCscQThread created", __FUNCTION__); |
| |
| m_postPictureGscThread = new mainCameraThread(this, &ExynosCamera::m_postPictureGscThreadFunc, "m_postPictureGscThread"); |
| CLOGD("DEBUG(%s): m_postPictureGscThread created", __FUNCTION__); |
| |
| #ifdef SAMSUNG_LBP |
| m_LBPThread = new mainCameraThread(this, &ExynosCamera::m_LBPThreadFunc, "LBPThread"); |
| CLOGD("DEBUG(%s): LBPThread created", __FUNCTION__); |
| #endif |
| #ifdef SAMSUNG_DNG |
| /* m_DNGCaptureThread */ |
| m_DNGCaptureThread = new mainCameraThread(this, &ExynosCamera::m_DNGCaptureThreadFunc, "m_DNGCaptureThread"); |
| CLOGD("DEBUG(%s):m_DNGCaptureThread created", __FUNCTION__); |
| #endif |
| |
| #ifdef SAMSUNG_SENSOR_LISTENER |
| m_sensorListenerThread = new mainCameraThread(this, &ExynosCamera::m_sensorListenerThreadFunc, "sensorListenerThread"); |
| CLOGD("DEBUG(%s):m_sensorListenerThread created", __FUNCTION__); |
| #endif |
| |
| #ifdef SAMSUNG_LLS_DEBLUR |
| /* m_LDCapture Thread */ |
| m_LDCaptureThread = new mainCameraThread(this, &ExynosCamera::m_LDCaptureThreadFunc, "m_LDCaptureThread"); |
| CLOGD("DEBUG(%s):m_LDCaptureThread created", __FUNCTION__); |
| #endif |
| |
| /* saveThread */ |
| char threadName[20]; |
| for (int threadNum = JPEG_SAVE_THREAD0; threadNum < JPEG_SAVE_THREAD_MAX_COUNT; threadNum++) { |
| snprintf(threadName, sizeof(threadName), "jpegSaveThread%d", threadNum); |
| m_jpegSaveThread[threadNum] = new mainCameraThread(this, &ExynosCamera::m_jpegSaveThreadFunc, threadName); |
| CLOGD("DEBUG(%s):%s created", __FUNCTION__, threadName); |
| } |
| |
| /* high resolution preview callback Thread */ |
| m_highResolutionCallbackThread = new mainCameraThread(this, &ExynosCamera::m_highResolutionCallbackThreadFunc, "m_highResolutionCallbackThread"); |
| CLOGD("DEBUG(%s):highResolutionCallbackThread created", __FUNCTION__); |
| |
| /* vision */ |
| m_visionThread = new mainCameraThread(this, &ExynosCamera::m_visionThreadFunc, "VisionThread", PRIORITY_URGENT_DISPLAY); |
| CLOGD("DEBUG(%s):visionThread created", __FUNCTION__); |
| |
| /* Shutter callback */ |
| m_shutterCallbackThread = new mainCameraThread(this, &ExynosCamera::m_shutterCallbackThreadFunc, "shutterCallbackThread"); |
| CLOGD("DEBUG(%s):shutterCallbackThread created", __FUNCTION__); |
| |
| /* m_ThumbnailCallback Thread */ |
| m_ThumbnailCallbackThread = new mainCameraThread(this, &ExynosCamera::m_ThumbnailCallbackThreadFunc, "m_ThumbnailCallbackThread"); |
| CLOGD("DEBUG(%s):m_ThumbnailCallbackThread created", __FUNCTION__); |
| |
| #ifdef SAMSUNG_DEBLUR |
| /* m_deblurCapture Thread */ |
| m_deblurCaptureThread = new mainCameraThread(this, &ExynosCamera::m_deblurCaptureThreadFunc, "m_deblurCaptureThread"); |
| CLOGD("DEBUG(%s):m_deblurCaptureThread created", __FUNCTION__); |
| |
| /* m_detectDeblurCapture Thread */ |
| m_detectDeblurCaptureThread = new mainCameraThread(this, &ExynosCamera::m_detectDeblurCaptureThreadFunc, "m_detectDeblurCaptureThread"); |
| CLOGD("DEBUG(%s):m_detectDeblurCaptureThread created", __FUNCTION__); |
| #endif |
| |
| #ifdef RAWDUMP_CAPTURE |
| /* RawCaptureDump Thread */ |
| m_RawCaptureDumpThread = new mainCameraThread(this, &ExynosCamera::m_RawCaptureDumpThreadFunc, "m_RawCaptureDumpThread"); |
| CLOGD("DEBUG(%s):RawCaptureDumpThread created", __FUNCTION__); |
| #endif |
| |
| #ifdef CAMERA_FAST_ENTRANCE_V1 |
| m_fastenAeThread = new mainCameraThread(this, &ExynosCamera::m_fastenAeThreadFunc, "fastenAeThread"); |
| CLOGD("DEBUG(%s):m_fastenAeThread created", __FUNCTION__); |
| #endif |
| } |
| |
| status_t ExynosCamera::m_setupFrameFactory(void) |
| { |
| CLOGI("INFO(%s[%d]): -IN-", __FUNCTION__, __LINE__); |
| |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| |
| status_t ret = NO_ERROR; |
| |
| if (m_exynosCameraParameters->getVisionMode() == true) { |
| /* about vision */ |
| if( m_frameFactory[FRAME_FACTORY_TYPE_VISION] == NULL) { |
| m_frameFactory[FRAME_FACTORY_TYPE_VISION] = new ExynosCameraFrameFactoryVision(m_cameraId, m_exynosCameraParameters); |
| m_frameFactory[FRAME_FACTORY_TYPE_VISION]->setFrameManager(m_frameMgr); |
| } |
| m_visionFrameFactory = m_frameFactory[FRAME_FACTORY_TYPE_VISION]; |
| |
| if (m_frameFactory[FRAME_FACTORY_TYPE_VISION] != NULL && m_frameFactory[FRAME_FACTORY_TYPE_VISION]->isCreated() == false) { |
| CLOGD("DEBUG(%s[%d]):setupFrameFactory pushProcessQ(%d)", __FUNCTION__, __LINE__, FRAME_FACTORY_TYPE_VISION); |
| m_frameFactoryQ->pushProcessQ(&m_frameFactory[FRAME_FACTORY_TYPE_VISION]); |
| } |
| } else { |
| ExynosCameraFrameFactory *curPreviewFrameFactory = m_previewFrameFactory; |
| |
| /* about preview */ |
| if (m_exynosCameraParameters->getDualMode() == true) { |
| m_previewFrameFactory = m_frameFactory[FRAME_FACTORY_TYPE_DUAL_PREVIEW]; |
| } else if (m_exynosCameraParameters->getTpuEnabledMode() == true) { |
| if (m_exynosCameraParameters->is3aaIspOtf() == true) |
| m_previewFrameFactory = m_frameFactory[FRAME_FACTORY_TYPE_3AA_ISP_OTF_TPU]; |
| else |
| m_previewFrameFactory = m_frameFactory[FRAME_FACTORY_TYPE_3AA_ISP_M2M_TPU]; |
| } else { |
| if (m_exynosCameraParameters->is3aaIspOtf() == true) |
| m_previewFrameFactory = m_frameFactory[FRAME_FACTORY_TYPE_3AA_ISP_OTF]; |
| else |
| m_previewFrameFactory = m_frameFactory[FRAME_FACTORY_TYPE_3AA_ISP_M2M]; |
| } |
| |
| /* |
| * (by h/w path changing scenario) frameFactory will be changed |
| * we must destroy these.(to close device) |
| * 1. reprocessing frameFactory |
| * 2. preview framFactory |
| * 3. companion |
| */ |
| if (curPreviewFrameFactory != NULL && |
| curPreviewFrameFactory != m_previewFrameFactory) { |
| CLOGD("DEBUG(%s[%d]):previewFrameFactory is changed. so, destroy all frameFactory", __FUNCTION__, __LINE__); |
| |
| if (m_reprocessingFrameFactory != NULL && |
| m_reprocessingFrameFactory->isCreated() == true) { |
| CLOGD("DEBUG(%s[%d]):destory old reprocessing FrameFactory", __FUNCTION__, __LINE__); |
| m_reprocessingFrameFactory->destroy(); |
| } |
| |
| if (curPreviewFrameFactory->isCreated() == true) { |
| CLOGD("DEBUG(%s[%d]):destory old frameFactory", __FUNCTION__, __LINE__); |
| curPreviewFrameFactory->destroy(); |
| |
| m_stopCompanion(); |
| |
| m_startCompanion(); |
| /* start CompanionThread. startPreview()'s m_waitCompanionThreadEnd() will wait */ |
| //m_waitCompanionThreadEnd(); |
| } |
| } |
| |
| /* find previewFrameFactory and push */ |
| for (int i = 0; i < FRAME_FACTORY_TYPE_MAX; i++) { |
| if (m_previewFrameFactory == m_frameFactory[i]) { |
| if (m_frameFactory[i] != NULL && m_frameFactory[i]->isCreated() == false) { |
| CLOGD("DEBUG(%s[%d]):setupFrameFactory pushProcessQ(%d)", __FUNCTION__, __LINE__, i); |
| m_frameFactoryQ->pushProcessQ(&m_frameFactory[i]); |
| } |
| break; |
| } |
| } |
| |
| /* about reprocessing */ |
| if (m_exynosCameraParameters->isReprocessing() == true) { |
| m_reprocessingFrameFactory = m_frameFactory[FRAME_FACTORY_TYPE_REPROCESSING]; |
| |
| if (m_frameFactory[FRAME_FACTORY_TYPE_REPROCESSING] != NULL && m_frameFactory[FRAME_FACTORY_TYPE_REPROCESSING]->isCreated() == false) { |
| CLOGD("DEBUG(%s[%d]):setupFrameFactory pushProcessQ(%d)", __FUNCTION__, __LINE__, FRAME_FACTORY_TYPE_REPROCESSING); |
| m_frameFactoryQ->pushProcessQ(&m_frameFactory[FRAME_FACTORY_TYPE_REPROCESSING]); |
| } |
| } |
| } |
| |
| /* |
| * disable until multi-instace is possible. |
| */ |
| /* |
| for (int i = 0; i < FRAME_FACTORY_TYPE_MAX; i++) { |
| if (m_frameFactory[i] != NULL && m_frameFactory[i]->isCreated() == false) { |
| CLOGD("DEBUG(%s[%d]):setupFrameFactory pushProcessQ(%d)", __FUNCTION__, __LINE__, i); |
| m_frameFactoryQ->pushProcessQ(&m_frameFactory[i]); |
| } else { |
| CLOGD("DEBUG(%s[%d]):setupFrameFactory no Push(%d)", __FUNCTION__, __LINE__, i); |
| } |
| } |
| */ |
| |
| CLOGI("INFO(%s[%d]): -OUT-", __FUNCTION__, __LINE__); |
| |
| return ret; |
| } |
| |
| status_t ExynosCamera::m_initFrameFactory(void) |
| { |
| CLOGI("INFO(%s[%d]): -IN-", __FUNCTION__, __LINE__); |
| |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| status_t ret = NO_ERROR; |
| ExynosCameraFrameFactory *factory = NULL; |
| |
| m_previewFrameFactory = NULL; |
| m_pictureFrameFactory = NULL; |
| m_reprocessingFrameFactory = NULL; |
| m_visionFrameFactory = NULL; |
| |
| for(int i = 0; i < FRAME_FACTORY_TYPE_MAX; i++) |
| m_frameFactory[i] = NULL; |
| |
| /* |
| * new all FrameFactories. |
| * because this called on open(). so we don't know current scenario |
| */ |
| |
| factory = new ExynosCameraFrameFactory3aaIspTpu(m_cameraId, m_exynosCameraParameters); |
| m_frameFactory[FRAME_FACTORY_TYPE_3AA_ISP_M2M] = factory; |
| /* hack : for dual */ |
| if (getCameraId() == CAMERA_ID_FRONT) { |
| factory = new ExynosCameraFrameFactoryFront(m_cameraId, m_exynosCameraParameters); |
| m_frameFactory[FRAME_FACTORY_TYPE_DUAL_PREVIEW] = factory; |
| } else { |
| factory = m_frameFactory[FRAME_FACTORY_TYPE_3AA_ISP_M2M]; |
| m_frameFactory[FRAME_FACTORY_TYPE_DUAL_PREVIEW] = factory; |
| } |
| |
| factory = m_frameFactory[FRAME_FACTORY_TYPE_3AA_ISP_M2M]; |
| m_frameFactory[FRAME_FACTORY_TYPE_3AA_ISP_M2M_TPU] = factory; |
| |
| factory = new ExynosCameraFrameFactory3aaIspOtf(m_cameraId, m_exynosCameraParameters); |
| m_frameFactory[FRAME_FACTORY_TYPE_3AA_ISP_OTF] = factory; |
| |
| factory = new ExynosCameraFrameFactory3aaIspOtfTpu(m_cameraId, m_exynosCameraParameters); |
| m_frameFactory[FRAME_FACTORY_TYPE_3AA_ISP_OTF_TPU] = factory; |
| |
| factory = new ExynosCameraFrameReprocessingFactory(m_cameraId, m_exynosCameraParameters); |
| m_frameFactory[FRAME_FACTORY_TYPE_REPROCESSING] = factory; |
| |
| for (int i = 0 ; i < FRAME_FACTORY_TYPE_MAX ; i++) { |
| factory = m_frameFactory[i]; |
| if( factory != NULL ) |
| factory->setFrameManager(m_frameMgr); |
| } |
| |
| CLOGI("INFO(%s[%d]): -OUT-", __FUNCTION__, __LINE__); |
| |
| return ret; |
| } |
| |
| status_t ExynosCamera::m_deinitFrameFactory(void) |
| { |
| CLOGI("INFO(%s[%d]): -IN-", __FUNCTION__, __LINE__); |
| |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| |
| status_t ret = NO_ERROR; |
| ExynosCameraFrameFactory *frameFactory = NULL; |
| |
| for (int i = 0; i < FRAME_FACTORY_TYPE_MAX; i++) { |
| if (m_frameFactory[i] != NULL) { |
| frameFactory = m_frameFactory[i]; |
| |
| for (int k = i + 1; k < FRAME_FACTORY_TYPE_MAX; k++) { |
| if (frameFactory == m_frameFactory[k]) { |
| CLOGD("DEBUG(%s[%d]): m_frameFactory index(%d) and index(%d) are same instance, set index(%d) = NULL", |
| __FUNCTION__, __LINE__, i, k, k); |
| m_frameFactory[k] = NULL; |
| } |
| } |
| |
| if (m_frameFactory[i]->isCreated() == true) { |
| ret = m_frameFactory[i]->destroy(); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):m_frameFactory[%d] destroy fail", __FUNCTION__, __LINE__, i); |
| } |
| |
| SAFE_DELETE(m_frameFactory[i]); |
| |
| CLOGD("DEBUG(%s[%d]):m_frameFactory[%d] destroyed", __FUNCTION__, __LINE__, i); |
| } |
| } |
| |
| m_previewFrameFactory = NULL; |
| m_pictureFrameFactory = NULL; |
| m_reprocessingFrameFactory = NULL; |
| m_visionFrameFactory = NULL; |
| |
| CLOGI("INFO(%s[%d]): -OUT-", __FUNCTION__, __LINE__); |
| |
| return ret; |
| } |
| |
| status_t ExynosCamera::m_setFrameManager() |
| { |
| sp<FrameWorker> worker; |
| m_frameMgr = new ExynosCameraFrameManager("FRAME MANAGER", m_cameraId, FRAMEMGR_OPER::SLIENT, 100, 150); |
| |
| worker = new CreateWorker("CREATE FRAME WORKER", m_cameraId, FRAMEMGR_OPER::SLIENT, 200); |
| m_frameMgr->setWorker(FRAMEMGR_WORKER::CREATE, worker); |
| |
| worker = new DeleteWorker("DELETE FRAME WORKER", m_cameraId, FRAMEMGR_OPER::SLIENT); |
| m_frameMgr->setWorker(FRAMEMGR_WORKER::DELETE, worker); |
| |
| sp<KeyBox> key = new KeyBox("FRAME KEYBOX", m_cameraId); |
| |
| m_frameMgr->setKeybox(key); |
| |
| return NO_ERROR; |
| } |
| |
| |
| ExynosCamera::~ExynosCamera() |
| { |
| this->release(); |
| } |
| |
| void ExynosCamera::release() |
| { |
| CLOGI("INFO(%s[%d]): -IN-", __FUNCTION__, __LINE__); |
| int ret = 0; |
| |
| #ifdef CAMERA_FAST_ENTRANCE_V1 |
| if (m_fastenAeThread != NULL) { |
| CLOGI("INFO(%s[%d]): wait m_fastenAeThread", __FUNCTION__, __LINE__); |
| m_fastenAeThread->requestExitAndWait(); |
| CLOGI("INFO(%s[%d]): wait m_fastenAeThread end", __FUNCTION__, __LINE__); |
| } else { |
| CLOGI("INFO(%s[%d]):m_fastenAeThread is NULL", __FUNCTION__, __LINE__); |
| } |
| #endif |
| |
| m_stopCompanion(); |
| |
| if (m_frameMgr != NULL) { |
| m_frameMgr->stop(); |
| } |
| |
| /* release all framefactory */ |
| m_deinitFrameFactory(); |
| |
| if (m_exynosCameraParameters != NULL) { |
| delete m_exynosCameraParameters; |
| m_exynosCameraParameters = NULL; |
| CLOGD("DEBUG(%s):Parameters(Id=%d) destroyed", __FUNCTION__, m_cameraId); |
| } |
| |
| /* free all buffers */ |
| m_releaseBuffers(); |
| |
| if (mIonClient >= 0) { |
| ion_close(mIonClient); |
| mIonClient = -1; |
| } |
| |
| if (m_ionAllocator != NULL) { |
| delete m_ionAllocator; |
| m_ionAllocator = NULL; |
| } |
| |
| if (m_grAllocator != NULL) { |
| delete m_grAllocator; |
| m_grAllocator = NULL; |
| } |
| |
| if (m_mhbAllocator != NULL) { |
| delete m_mhbAllocator; |
| m_mhbAllocator = NULL; |
| } |
| |
| if (m_pipeFrameDoneQ != NULL) { |
| delete m_pipeFrameDoneQ; |
| m_pipeFrameDoneQ = NULL; |
| } |
| |
| if (m_zoomPreviwWithCscQ != NULL) { |
| delete m_zoomPreviwWithCscQ; |
| m_zoomPreviwWithCscQ = NULL; |
| } |
| |
| /* vision */ |
| if (m_pipeFrameVisionDoneQ != NULL) { |
| delete m_pipeFrameVisionDoneQ; |
| m_pipeFrameVisionDoneQ = NULL; |
| } |
| |
| if (dstIspReprocessingQ != NULL) { |
| delete dstIspReprocessingQ; |
| dstIspReprocessingQ = NULL; |
| } |
| |
| if (dstSccReprocessingQ != NULL) { |
| delete dstSccReprocessingQ; |
| dstSccReprocessingQ = NULL; |
| } |
| |
| if (dstGscReprocessingQ != NULL) { |
| delete dstGscReprocessingQ; |
| dstGscReprocessingQ = NULL; |
| } |
| |
| if (dstPostPictureGscQ != NULL) { |
| delete dstPostPictureGscQ; |
| dstPostPictureGscQ = NULL; |
| } |
| |
| if (m_ThumbnailPostCallbackQ != NULL) { |
| delete m_ThumbnailPostCallbackQ; |
| m_ThumbnailPostCallbackQ = NULL; |
| } |
| |
| if (dstJpegReprocessingQ != NULL) { |
| delete dstJpegReprocessingQ; |
| dstJpegReprocessingQ = NULL; |
| } |
| |
| if (m_postPictureQ != NULL) { |
| delete m_postPictureQ; |
| m_postPictureQ = NULL; |
| } |
| |
| #ifdef SAMSUNG_DEBLUR |
| if (m_deblurCaptureQ != NULL) { |
| delete m_deblurCaptureQ; |
| m_deblurCaptureQ = NULL; |
| } |
| |
| if (m_detectDeblurCaptureQ != NULL) { |
| delete m_detectDeblurCaptureQ; |
| m_detectDeblurCaptureQ = NULL; |
| } |
| #endif |
| |
| if (m_jpegCallbackQ != NULL) { |
| delete m_jpegCallbackQ; |
| m_jpegCallbackQ = NULL; |
| } |
| |
| if (m_postviewCallbackQ != NULL) { |
| delete m_postviewCallbackQ; |
| m_postviewCallbackQ = NULL; |
| } |
| |
| if (m_thumbnailCallbackQ != NULL) { |
| delete m_thumbnailCallbackQ; |
| m_thumbnailCallbackQ = NULL; |
| } |
| |
| #ifdef SAMSUNG_LBP |
| if (m_LBPbufferQ != NULL) { |
| delete m_LBPbufferQ; |
| m_LBPbufferQ = NULL; |
| } |
| #endif |
| |
| #ifdef SAMSUNG_DNG |
| if (m_dngCaptureQ != NULL) { |
| delete m_dngCaptureQ; |
| m_dngCaptureQ = NULL; |
| } |
| #endif |
| |
| #ifdef SAMSUNG_BD |
| if (m_BDbufferQ != NULL) { |
| delete m_BDbufferQ; |
| m_BDbufferQ = NULL; |
| } |
| #endif |
| |
| #ifdef SAMSUNG_LLS_DEBLUR |
| if (m_LDCaptureQ != NULL) { |
| delete m_LDCaptureQ; |
| m_LDCaptureQ = NULL; |
| } |
| #endif |
| |
| if (m_facedetectQ != NULL) { |
| delete m_facedetectQ; |
| m_facedetectQ = NULL; |
| } |
| |
| if (m_previewQ != NULL) { |
| delete m_previewQ; |
| m_previewQ = NULL; |
| } |
| |
| for(int i = 0 ; i < MAX_NUM_PIPES ; i++ ) { |
| if (m_mainSetupQ[i] != NULL) { |
| delete m_mainSetupQ[i]; |
| m_mainSetupQ[i] = NULL; |
| } |
| } |
| |
| if (m_previewCallbackGscFrameDoneQ != NULL) { |
| delete m_previewCallbackGscFrameDoneQ; |
| m_previewCallbackGscFrameDoneQ = NULL; |
| } |
| |
| if (m_recordingQ != NULL) { |
| delete m_recordingQ; |
| m_recordingQ = NULL; |
| } |
| |
| for (int threadNum = JPEG_SAVE_THREAD0; threadNum < JPEG_SAVE_THREAD_MAX_COUNT; threadNum++) { |
| if (m_jpegSaveQ[threadNum] != NULL) { |
| delete m_jpegSaveQ[threadNum]; |
| m_jpegSaveQ[threadNum] = NULL; |
| } |
| } |
| |
| if (m_highResolutionCallbackQ != NULL) { |
| delete m_highResolutionCallbackQ; |
| m_highResolutionCallbackQ = NULL; |
| } |
| |
| if (m_frameFactoryQ != NULL) { |
| delete m_frameFactoryQ; |
| m_frameFactoryQ = NULL; |
| CLOGD("DEBUG(%s):FrameFactoryQ destroyed", __FUNCTION__); |
| } |
| |
| if (m_bayerBufferMgr != NULL) { |
| delete m_bayerBufferMgr; |
| m_bayerBufferMgr = NULL; |
| CLOGD("DEBUG(%s):BufferManager(bayerBufferMgr) destroyed", __FUNCTION__); |
| } |
| |
| #ifdef SAMSUNG_DNG |
| if (m_fliteBufferMgr != NULL) { |
| delete m_fliteBufferMgr; |
| m_fliteBufferMgr = NULL; |
| CLOGD("DEBUG(%s):BufferManager(m_fliteBufferMgr) destroyed", __FUNCTION__); |
| } |
| #endif |
| |
| if (m_3aaBufferMgr != NULL) { |
| delete m_3aaBufferMgr; |
| m_3aaBufferMgr = NULL; |
| CLOGD("DEBUG(%s):BufferManager(3aaBufferMgr) destroyed", __FUNCTION__); |
| } |
| |
| if (m_ispBufferMgr != NULL) { |
| delete m_ispBufferMgr; |
| m_ispBufferMgr = NULL; |
| CLOGD("DEBUG(%s):BufferManager(ispBufferMgr) destroyed", __FUNCTION__); |
| } |
| |
| if (m_hwDisBufferMgr != NULL) { |
| delete m_hwDisBufferMgr; |
| m_hwDisBufferMgr = NULL; |
| CLOGD("DEBUG(%s):BufferManager(m_hwDisBufferMgr) destroyed", __FUNCTION__); |
| } |
| |
| if (m_scpBufferMgr != NULL) { |
| delete m_scpBufferMgr; |
| m_scpBufferMgr = NULL; |
| CLOGD("DEBUG(%s):BufferManager(scpBufferMgr) destroyed", __FUNCTION__); |
| } |
| |
| if (m_zoomScalerBufferMgr != NULL) { |
| delete m_zoomScalerBufferMgr; |
| m_zoomScalerBufferMgr = NULL; |
| CLOGD("DEBUG(%s):BufferManager(m_zoomScalerBufferMgr) destroyed", __FUNCTION__); |
| } |
| |
| if (m_ispReprocessingBufferMgr != NULL) { |
| delete m_ispReprocessingBufferMgr; |
| m_ispReprocessingBufferMgr = NULL; |
| CLOGD("DEBUG(%s):BufferManager(ispReprocessingBufferMgr) destroyed", __FUNCTION__); |
| } |
| |
| if (m_sccReprocessingBufferMgr != NULL) { |
| delete m_sccReprocessingBufferMgr; |
| m_sccReprocessingBufferMgr = NULL; |
| CLOGD("DEBUG(%s):BufferManager(sccReprocessingBufferMgr) destroyed", __FUNCTION__); |
| } |
| |
| if (m_sccBufferMgr != NULL) { |
| delete m_sccBufferMgr; |
| m_sccBufferMgr = NULL; |
| CLOGD("DEBUG(%s):BufferManager(sccBufferMgr) destroyed", __FUNCTION__); |
| } |
| |
| if (m_gscBufferMgr != NULL) { |
| delete m_gscBufferMgr; |
| m_gscBufferMgr = NULL; |
| CLOGD("DEBUG(%s):BufferManager(gscBufferMgr) destroyed", __FUNCTION__); |
| } |
| |
| if (m_postPictureGscBufferMgr != NULL) { |
| delete m_postPictureGscBufferMgr; |
| m_postPictureGscBufferMgr = NULL; |
| CLOGD("DEBUG(%s):BufferManager(m_postPictureGscBufferMgr) destroyed", __FUNCTION__); |
| } |
| |
| if (m_thumbnailGscBufferMgr != NULL) { |
| delete m_thumbnailGscBufferMgr; |
| m_thumbnailGscBufferMgr = NULL; |
| CLOGD("DEBUG(%s):BufferManager(m_thumbnailGscBufferMgr) destroyed", __FUNCTION__); |
| } |
| |
| #ifdef SAMSUNG_LBP |
| if (m_lbpBufferMgr != NULL) { |
| delete m_lbpBufferMgr; |
| m_lbpBufferMgr = NULL; |
| CLOGD("DEBUG(%s):BufferManager(lbpBufferMgr) destroyed", __FUNCTION__); |
| } |
| #endif |
| |
| if (m_jpegBufferMgr != NULL) { |
| delete m_jpegBufferMgr; |
| m_jpegBufferMgr = NULL; |
| CLOGD("DEBUG(%s):BufferManager(jpegBufferMgr) destroyed", __FUNCTION__); |
| } |
| |
| if (m_previewCallbackBufferMgr != NULL) { |
| delete m_previewCallbackBufferMgr; |
| m_previewCallbackBufferMgr = NULL; |
| CLOGD("DEBUG(%s):BufferManager(previewCallbackBufferMgr) destroyed", __FUNCTION__); |
| } |
| |
| if (m_highResolutionCallbackBufferMgr != NULL) { |
| delete m_highResolutionCallbackBufferMgr; |
| m_highResolutionCallbackBufferMgr = NULL; |
| CLOGD("DEBUG(%s):BufferManager(m_highResolutionCallbackBufferMgr) destroyed", __FUNCTION__); |
| } |
| |
| if (m_recordingBufferMgr != NULL) { |
| delete m_recordingBufferMgr; |
| m_recordingBufferMgr = NULL; |
| CLOGD("DEBUG(%s):BufferManager(recordingBufferMgr) destroyed", __FUNCTION__); |
| } |
| |
| if (m_captureSelector != NULL) { |
| delete m_captureSelector; |
| m_captureSelector = NULL; |
| } |
| |
| if (m_sccCaptureSelector != NULL) { |
| delete m_sccCaptureSelector; |
| m_sccCaptureSelector = NULL; |
| } |
| |
| if (m_recordingCallbackHeap != NULL) { |
| m_recordingCallbackHeap->release(m_recordingCallbackHeap); |
| delete m_recordingCallbackHeap; |
| m_recordingCallbackHeap = NULL; |
| CLOGD("DEBUG(%s):BufferManager(recordingCallbackHeap) destroyed", __FUNCTION__); |
| } |
| #ifdef SUPPORT_SW_VDIS |
| if (m_swVDIS_BufferMgr != NULL) { |
| delete m_swVDIS_BufferMgr; |
| m_swVDIS_BufferMgr = NULL; |
| VDIS_LOG("VDIS_HAL(%s):BufferManager(m_swVDIS_BufferMgr) destroyed", __FUNCTION__); |
| } |
| #endif /*SUPPORT_SW_VDIS*/ |
| |
| #ifdef SAMSUNG_LLV |
| if(m_LLVpluginHandle != NULL) { |
| ret = uni_plugin_unload(&m_LLVpluginHandle); |
| if(ret < 0) { |
| CLOGE("[LLV](%s[%d]):LLV plugin unload failed!!", __FUNCTION__, __LINE__); |
| } |
| } |
| #endif |
| |
| #ifdef SAMSUNG_OT |
| if(m_OTpluginHandle != NULL) { |
| ret = uni_plugin_unload(&m_OTpluginHandle); |
| if(ret < 0) { |
| CLOGE("[OBTR](%s[%d]):Object Tracking plugin unload failed!!", __FUNCTION__, __LINE__); |
| } |
| } |
| #endif |
| |
| #ifdef SAMSUNG_LBP |
| if(m_LBPpluginHandle != NULL) { |
| ret = uni_plugin_unload(&m_LBPpluginHandle); |
| if(ret < 0) { |
| CLOGE("[LBP](%s[%d]):Bestphoto plugin unload failed!!", __FUNCTION__, __LINE__); |
| } |
| } |
| #endif |
| |
| #ifdef SAMSUNG_JQ |
| if(m_JQpluginHandle != NULL) { |
| ret = uni_plugin_unload(&m_JQpluginHandle); |
| if(ret < 0) { |
| CLOGE("[JQ](%s[%d]):JPEG Qtable plugin unload failed!!", __FUNCTION__, __LINE__); |
| } |
| } |
| #endif |
| |
| #ifdef SAMSUNG_BD |
| if(m_BDpluginHandle != NULL) { |
| ret = uni_plugin_unload(&m_BDpluginHandle); |
| if(ret < 0) { |
| CLOGE("[BD](%s[%d]):Blur Detection plugin unload failed!!", __FUNCTION__, __LINE__); |
| } |
| } |
| #endif |
| |
| #ifdef SAMSUNG_DEBLUR |
| if(m_DeblurpluginHandle != NULL) { |
| ret = uni_plugin_unload(&m_DeblurpluginHandle); |
| if(ret < 0) { |
| CLOGE("[Deblur](%s[%d]):Deblur plugin unload failed!!", __FUNCTION__, __LINE__); |
| } |
| } |
| #if 0 |
| if(m_ImgScreenerpluginHandle != NULL) { |
| ret = uni_plugin_unload(&m_ImgScreenerpluginHandle); |
| if(ret < 0) { |
| CLOGE("[Deblur](%s[%d]):Image Screener plugin unload failed!!", __FUNCTION__, __LINE__); |
| } |
| } |
| #endif |
| #endif |
| |
| #ifdef SAMSUNG_LLS_DEBLUR |
| if(m_LLSpluginHandle != NULL) { |
| ret = uni_plugin_unload(&m_LLSpluginHandle); |
| if(ret < 0) { |
| CLOGE("[LDC](%s[%d]):LLS plugin unload failed!!", __FUNCTION__, __LINE__); |
| } |
| } |
| #endif |
| |
| m_isFirstStart = true; |
| m_previewBufferCount = NUM_PREVIEW_BUFFERS; |
| |
| if (m_frameMgr != NULL) { |
| delete m_frameMgr; |
| m_frameMgr = NULL; |
| } |
| |
| if (m_tempshot != NULL) { |
| delete m_tempshot; |
| m_tempshot = NULL; |
| } |
| |
| if (m_fdmeta_shot != NULL) { |
| delete m_fdmeta_shot; |
| m_fdmeta_shot = NULL; |
| } |
| |
| if (m_meta_shot != NULL) { |
| delete m_meta_shot; |
| m_meta_shot = NULL; |
| } |
| |
| #ifdef SUPPORT_SW_VDIS |
| if (m_swVDIS_fd_dm != NULL) { |
| delete m_swVDIS_fd_dm; |
| m_swVDIS_fd_dm = NULL; |
| } |
| |
| if (m_swVDIS_FaceData != NULL) { |
| delete m_swVDIS_FaceData; |
| m_swVDIS_FaceData = NULL; |
| } |
| #endif /*SUPPORT_SW_VDIS*/ |
| |
| #ifdef SAMSUNG_HRM |
| if(m_uv_rayHandle != NULL) { |
| sensor_listener_disable_sensor(m_uv_rayHandle, ST_UV_RAY); |
| sensor_listener_unload(&m_uv_rayHandle); |
| m_uv_rayHandle = NULL; |
| } |
| #endif |
| |
| #ifdef SAMSUNG_LIGHT_IR |
| if(m_light_irHandle != NULL) { |
| sensor_listener_disable_sensor(m_light_irHandle, ST_LIGHT_IR); |
| sensor_listener_unload(&m_light_irHandle); |
| m_light_irHandle = NULL; |
| } |
| #endif |
| |
| #ifdef SAMSUNG_GYRO |
| if(m_gyroHandle != NULL) { |
| sensor_listener_disable_sensor(m_gyroHandle, ST_GYROSCOPE); |
| sensor_listener_unload(&m_gyroHandle); |
| m_gyroHandle = NULL; |
| } |
| #endif |
| |
| CLOGI("INFO(%s[%d]): -OUT-", __FUNCTION__, __LINE__); |
| } |
| |
| int ExynosCamera::getCameraId() const |
| { |
| return m_cameraId; |
| } |
| |
| int ExynosCamera::getShotBufferIdex() const |
| { |
| return NUM_PLANES(V4L2_PIX_2_HAL_PIXEL_FORMAT(SCC_OUTPUT_COLOR_FMT)); |
| } |
| |
| status_t ExynosCamera::setPreviewWindow(preview_stream_ops *w) |
| { |
| CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__); |
| |
| status_t ret = NO_ERROR; |
| int width, height; |
| int halPreviewFmt = 0; |
| bool flagRestart = false; |
| buffer_manager_type bufferType = BUFFER_MANAGER_ION_TYPE; |
| |
| if (m_exynosCameraParameters != NULL) { |
| if (m_exynosCameraParameters->getVisionMode() == true) { |
| CLOGW("WRN(%s[%d]): Vision mode does not support", __FUNCTION__, __LINE__); |
| /* android_printAssert(NULL, LOG_TAG, "Cannot support this operation"); */ |
| |
| return NO_ERROR; |
| } |
| } else { |
| CLOGW("(%s):m_exynosCameraParameters is NULL. Skipped", __FUNCTION__); |
| return INVALID_OPERATION; |
| } |
| |
| if (previewEnabled() == true) { |
| CLOGW("WRN(%s[%d]): preview is started, we forcely re-start preview", __FUNCTION__, __LINE__); |
| flagRestart = true; |
| m_disablePreviewCB = true; |
| stopPreview(); |
| } |
| |
| m_previewWindow = w; |
| |
| if (m_scpBufferMgr != NULL) { |
| CLOGD("DEBUG(%s[%d]): scp buffer manager need recreate", __FUNCTION__, __LINE__); |
| m_scpBufferMgr->deinit(); |
| |
| delete m_scpBufferMgr; |
| m_scpBufferMgr = NULL; |
| } |
| |
| if (w == NULL) { |
| bufferType = BUFFER_MANAGER_ION_TYPE; |
| CLOGW("WARN(%s[%d]):window NULL, create internal buffer for preview", __FUNCTION__, __LINE__); |
| } else { |
| halPreviewFmt = m_exynosCameraParameters->getHalPixelFormat(); |
| bufferType = BUFFER_MANAGER_GRALLOC_TYPE; |
| m_exynosCameraParameters->getHwPreviewSize(&width, &height); |
| |
| if (m_grAllocator == NULL) |
| m_grAllocator = new ExynosCameraGrallocAllocator(); |
| |
| #ifdef RESERVED_MEMORY_FOR_GRALLOC_ENABLE |
| if (!(((m_exynosCameraParameters->getShotMode() == SHOT_MODE_BEAUTY_FACE) && (getCameraId() == CAMERA_ID_BACK)) |
| || m_exynosCameraParameters->getRecordingHint() == true)) { |
| ret = m_grAllocator->init(m_previewWindow, m_exynosconfig->current->bufInfo.num_preview_buffers, |
| m_exynosconfig->current->bufInfo.preview_buffer_margin, (GRALLOC_SET_USAGE_FOR_CAMERA | GRALLOC_USAGE_CAMERA_RESERVED)); |
| } else |
| #endif |
| { |
| ret = m_grAllocator->init(m_previewWindow, m_exynosconfig->current->bufInfo.num_preview_buffers, m_exynosconfig->current->bufInfo.preview_buffer_margin); |
| } |
| |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):gralloc init fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto func_exit; |
| } |
| |
| ret = m_grAllocator->setBuffersGeometry(width, height, halPreviewFmt); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):gralloc setBufferGeomety fail, size(%dx%d), fmt(%d), ret(%d)", |
| __FUNCTION__, __LINE__, width, height, halPreviewFmt, ret); |
| goto func_exit; |
| } |
| } |
| |
| m_createBufferManager(&m_scpBufferMgr, "SCP_BUF", bufferType); |
| |
| if (bufferType == BUFFER_MANAGER_GRALLOC_TYPE) |
| m_scpBufferMgr->setAllocator(m_grAllocator); |
| |
| if (flagRestart == true) { |
| startPreview(); |
| } |
| |
| func_exit: |
| m_disablePreviewCB = false; |
| |
| return ret; |
| } |
| |
| void ExynosCamera::setCallbacks( |
| camera_notify_callback notify_cb, |
| camera_data_callback data_cb, |
| camera_data_timestamp_callback data_cb_timestamp, |
| camera_request_memory get_memory, |
| void *user) |
| { |
| CLOGI("INFO(%s[%d]): -IN-", __FUNCTION__, __LINE__); |
| |
| int ret = 0; |
| |
| m_notifyCb = notify_cb; |
| m_dataCb = data_cb; |
| m_dataCbTimestamp = data_cb_timestamp; |
| m_getMemoryCb = get_memory; |
| m_callbackCookie = user; |
| |
| if (m_mhbAllocator == NULL) |
| m_mhbAllocator = new ExynosCameraMHBAllocator(); |
| |
| ret = m_mhbAllocator->init(get_memory); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]:m_mhbAllocator init failed", __FUNCTION__, __LINE__); |
| } |
| } |
| |
| void ExynosCamera::enableMsgType(int32_t msgType) |
| { |
| if (m_exynosCameraParameters) { |
| CLOGV("INFO(%s[%d]): enable Msg (%x)", __FUNCTION__, __LINE__, msgType); |
| m_exynosCameraParameters->enableMsgType(msgType); |
| } |
| } |
| |
| void ExynosCamera::disableMsgType(int32_t msgType) |
| { |
| if (m_exynosCameraParameters) { |
| CLOGV("INFO(%s[%d]): disable Msg (%x)", __FUNCTION__, __LINE__, msgType); |
| m_exynosCameraParameters->disableMsgType(msgType); |
| } |
| } |
| |
| bool ExynosCamera::msgTypeEnabled(int32_t msgType) |
| { |
| bool IsEnabled = false; |
| |
| if (m_exynosCameraParameters) { |
| CLOGV("INFO(%s[%d]): Msg type enabled (%x)", __FUNCTION__, __LINE__, msgType); |
| IsEnabled = m_exynosCameraParameters->msgTypeEnabled(msgType); |
| } |
| |
| return IsEnabled; |
| } |
| |
| status_t ExynosCamera::startPreview() |
| { |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| |
| CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__); |
| |
| int ret = 0; |
| int32_t skipFrameCount = INITIAL_SKIP_FRAME; |
| unsigned int fdCallbackSize = 0; |
| #ifdef SR_CAPTURE |
| unsigned int srCallbackSize = 0; |
| #endif |
| #ifdef CAMERA_FAST_ENTRANCE_V1 |
| int wait_cnt = 0; |
| #endif |
| |
| m_hdrSkipedFcount = 0; |
| m_isTryStopFlash= false; |
| m_exitAutoFocusThread = false; |
| m_curMinFps = 0; |
| m_isNeedAllocPictureBuffer = false; |
| m_flagThreadStop= false; |
| m_frameSkipCount = 0; |
| #ifndef CAMERA_FAST_ENTRANCE_V1 |
| m_checkFirstFrameLux = false; |
| #endif |
| m_exynosCameraParameters->setIsThumbnailCallbackOn(false); |
| m_stopLongExposure = false; |
| |
| #ifdef FIRST_PREVIEW_TIME_CHECK |
| if (m_flagFirstPreviewTimerOn == false) { |
| m_firstPreviewTimer.start(); |
| m_flagFirstPreviewTimerOn = true; |
| |
| CLOGD("DEBUG(%s[%d]):m_firstPreviewTimer start", __FUNCTION__, __LINE__); |
| } |
| #endif |
| |
| if (m_previewEnabled == true) { |
| return INVALID_OPERATION; |
| } |
| |
| #ifdef SAMSUNG_SENSOR_LISTENER |
| if(m_sensorListenerThread != NULL) |
| m_sensorListenerThread->run(); |
| #endif |
| |
| #ifdef FORCE_RESET_MULTI_FRAME_FACTORY |
| /* HACK |
| * stopPreview() close companion |
| * so. start here again |
| * The reason why we did't start compaion on stopPreview() is.. |
| * release() can be come just after stopPreview(). |
| * If it is, release can be delay by companion open and. then app make exception |
| */ |
| if (m_startCompanion() != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):m_startCompanion fail", __FUNCTION__, __LINE__); |
| } |
| #endif |
| |
| #ifdef CAMERA_FAST_ENTRANCE_V1 |
| if (m_fastEntrance == false) |
| #endif |
| { |
| /* frame manager start */ |
| m_frameMgr->start(); |
| } |
| |
| #ifdef SAMSUNG_DOF |
| fdCallbackSize = sizeof(camera_frame_metadata_t) * NUM_OF_DETECTED_FACES + |
| sizeof(camera2_pdaf_multi_result)*m_frameMetadata.dof_row*m_frameMetadata.dof_column; |
| #else |
| fdCallbackSize = sizeof(camera_frame_metadata_t) * NUM_OF_DETECTED_FACES; |
| #endif |
| |
| m_fdCallbackHeap = m_getMemoryCb(-1, fdCallbackSize, 1, m_callbackCookie); |
| if (!m_fdCallbackHeap || m_fdCallbackHeap->data == MAP_FAILED) { |
| CLOGE("ERR(%s[%d]):m_getMemoryCb(%d) fail", __FUNCTION__, __LINE__, fdCallbackSize); |
| m_fdCallbackHeap = NULL; |
| goto err; |
| } |
| |
| #ifdef SR_CAPTURE |
| srCallbackSize = sizeof(camera_frame_metadata_t) * NUM_OF_DETECTED_FACES; |
| |
| m_srCallbackHeap = m_getMemoryCb(-1, srCallbackSize, 1, m_callbackCookie); |
| if (!m_srCallbackHeap || m_srCallbackHeap->data == MAP_FAILED) { |
| CLOGE("ERR(%s[%d]):m_getMemoryCb(%d) fail", __FUNCTION__, __LINE__, srCallbackSize); |
| m_srCallbackHeap = NULL; |
| goto err; |
| } |
| #endif |
| |
| #ifdef SAMSUNG_LBP |
| if(getCameraId() == CAMERA_ID_FRONT) |
| m_exynosCameraParameters->resetNormalBestFrameCount(); |
| #endif |
| |
| #ifdef CAMERA_FAST_ENTRANCE_V1 |
| if (m_fastEntrance == true) { |
| /* In case m_previewFrameFactory is not created, wait for 1 sec */ |
| while (m_previewFrameFactory == NULL) { |
| if (wait_cnt > 200) { |
| CLOGE("ERR(%s[%d]): m_previewFrameFactory is not created for 1 SEC", __FUNCTION__, __LINE__); |
| break; |
| } |
| usleep(5000); |
| wait_cnt++; |
| |
| if (wait_cnt % 20 == 0) |
| CLOGW("WARN(%s[%d]): Waiting until m_previewFrameFactory create (wait_cnt %d)", |
| __FUNCTION__, __LINE__, wait_cnt); |
| } |
| } |
| else |
| #endif |
| { |
| /* |
| * This is for updating parameter value at once. |
| * This must be just before making factory |
| */ |
| m_exynosCameraParameters->updateTpuParameters(); |
| |
| /* setup frameFactory with scenario */ |
| m_setupFrameFactory(); |
| } |
| |
| /* vision */ |
| CLOGI("INFO(%s[%d]): getVisionMode(%d)", __FUNCTION__, __LINE__, m_exynosCameraParameters->getVisionMode()); |
| if (m_exynosCameraParameters->getVisionMode() == true) { |
| ret = m_setVisionBuffers(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_setVisionCallbackBuffer() fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| ret = m_setVisionCallbackBuffer(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_setVisionCallbackBuffer() fail", __FUNCTION__, __LINE__); |
| return INVALID_OPERATION; |
| } |
| |
| if (m_visionFrameFactory->isCreated() == false) { |
| ret = m_visionFrameFactory->create(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_visionFrameFactory->create() failed", __FUNCTION__, __LINE__); |
| goto err; |
| } |
| CLOGD("DEBUG(%s):FrameFactory(VisionFrameFactory) created", __FUNCTION__); |
| } |
| |
| m_exynosCameraParameters->setFrameSkipCount(INITIAL_SKIP_FRAME); |
| |
| ret = m_startVisionInternal(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_startVisionInternal() failed", __FUNCTION__, __LINE__); |
| goto err; |
| } |
| |
| m_visionThread->run(PRIORITY_DEFAULT); |
| return NO_ERROR; |
| } else { |
| m_exynosCameraParameters->setSeriesShotMode(SERIES_SHOT_MODE_NONE); |
| |
| if(m_exynosCameraParameters->increaseMaxBufferOfPreview()) { |
| m_exynosCameraParameters->setPreviewBufferCount(NUM_PREVIEW_BUFFERS + NUM_PREVIEW_SPARE_BUFFERS); |
| } else { |
| m_exynosCameraParameters->setPreviewBufferCount(NUM_PREVIEW_BUFFERS); |
| } |
| |
| #ifdef SUPPORT_SW_VDIS |
| m_swVDIS_Mode = false; |
| if(m_exynosCameraParameters->isSWVdisMode()) { |
| m_swVDIS_InW = m_swVDIS_InH = 0; |
| m_exynosCameraParameters->getHwPreviewSize(&m_swVDIS_InW, &m_swVDIS_InH); |
| m_swVDIS_CameraID = getCameraId(); |
| m_swVDIS_SensorType = getSensorId(m_swVDIS_CameraID); |
| #ifdef SAMSUNG_OIS_VDIS |
| m_swVDIS_OISMode = UNI_PLUGIN_OIS_MODE_VDIS; |
| m_OISvdisMode = UNI_PLUGIN_OIS_MODE_END; |
| #endif |
| m_swVDIS_init(); |
| |
| m_exynosCameraParameters->setPreviewBufferCount(NUM_VDIS_BUFFERS); |
| m_exynosconfig->current->bufInfo.num_preview_buffers = NUM_VDIS_BUFFERS; |
| VDIS_LOG("VDIS_HAL: Preview Buffer Count Change to %d", NUM_VDIS_BUFFERS); |
| } |
| #endif /*SUPPORT_SW_VDIS*/ |
| |
| if ((m_exynosCameraParameters->getRestartPreview() == true) || |
| m_previewBufferCount != m_exynosCameraParameters->getPreviewBufferCount()) { |
| ret = setPreviewWindow(m_previewWindow); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setPreviewWindow fail", __FUNCTION__, __LINE__); |
| return INVALID_OPERATION; |
| } |
| |
| m_previewBufferCount = m_exynosCameraParameters->getPreviewBufferCount(); |
| } |
| |
| #ifdef CAMERA_FAST_ENTRANCE_V1 |
| if (m_fastEntrance == true) { |
| ret = m_setBuffers(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_setBuffers failed, releaseBuffer", __FUNCTION__, __LINE__); |
| m_isSuccessedBufferAllocation = false; |
| goto err; |
| } |
| |
| m_isSuccessedBufferAllocation = true; |
| } else |
| #endif |
| { |
| CLOGI("INFO(%s[%d]):setBuffersThread is run", __FUNCTION__, __LINE__); |
| m_setBuffersThread->run(PRIORITY_DEFAULT); |
| } |
| |
| if (m_captureSelector == NULL) { |
| ExynosCameraBufferManager *bufMgr = NULL; |
| |
| if (m_exynosCameraParameters->isReprocessing() == true) |
| bufMgr = m_bayerBufferMgr; |
| |
| m_captureSelector = new ExynosCameraFrameSelector(m_exynosCameraParameters, bufMgr, m_frameMgr); |
| |
| if (m_exynosCameraParameters->isReprocessing() == true) { |
| ret = m_captureSelector->setFrameHoldCount(REPROCESSING_BAYER_HOLD_COUNT); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]): setFrameHoldCount(%d) is fail", __FUNCTION__, __LINE__, REPROCESSING_BAYER_HOLD_COUNT); |
| } |
| } |
| |
| if (m_sccCaptureSelector == NULL) { |
| ExynosCameraBufferManager *bufMgr = NULL; |
| if (m_exynosCameraParameters->isSccCapture() == true) { |
| /* TODO: Dynamic select buffer manager for capture */ |
| bufMgr = m_sccBufferMgr; |
| } |
| m_sccCaptureSelector = new ExynosCameraFrameSelector(m_exynosCameraParameters, bufMgr, m_frameMgr); |
| } |
| |
| if (m_captureSelector != NULL) |
| m_captureSelector->release(); |
| |
| if (m_sccCaptureSelector != NULL) |
| m_sccCaptureSelector->release(); |
| |
| #ifdef OIS_CAPTURE |
| ExynosCameraActivitySpecialCapture *m_sCaptureMgr = m_exynosCameraActivityControl->getSpecialCaptureMgr(); |
| m_sCaptureMgr->resetOISCaptureFcount(); |
| #endif |
| |
| #ifdef RAWDUMP_CAPTURE |
| ExynosCameraActivitySpecialCapture *m_sCapture = m_exynosCameraActivityControl->getSpecialCaptureMgr(); |
| m_sCapture->resetRawCaptureFcount(); |
| #endif |
| |
| if ((m_previewFrameFactory->isCreated() == false) |
| #ifdef CAMERA_FAST_ENTRANCE_V1 |
| && (m_fastEntrance == false) |
| #endif |
| ) { |
| #if defined(SAMSUNG_EEPROM) |
| if ((m_use_companion == false) && (isEEprom(getCameraId()) == true)) { |
| if (m_eepromThread != NULL) { |
| CLOGD("DEBUG(%s): eepromThread join.....", __FUNCTION__); |
| m_eepromThread->join(); |
| } else { |
| CLOGD("DEBUG(%s): eepromThread is NULL.", __FUNCTION__); |
| } |
| m_exynosCameraParameters->setRomReadThreadDone(true); |
| CLOGD("DEBUG(%s): eepromThread joined", __FUNCTION__); |
| } |
| #endif /* SAMSUNG_EEPROM */ |
| |
| #ifdef SAMSUNG_COMPANION |
| if(m_use_companion == true) { |
| ret = m_previewFrameFactory->precreate(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_previewFrameFactory->precreate() failed", __FUNCTION__, __LINE__); |
| goto err; |
| } |
| |
| m_waitCompanionThreadEnd(); |
| |
| m_exynosCameraParameters->setRomReadThreadDone(true); |
| |
| ret = m_previewFrameFactory->postcreate(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_previewFrameFactory->postcreate() failed", __FUNCTION__, __LINE__); |
| goto err; |
| } |
| } else { |
| ret = m_previewFrameFactory->create(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_previewFrameFactory->create() failed", __FUNCTION__, __LINE__); |
| goto err; |
| } |
| } |
| #else |
| ret = m_previewFrameFactory->create(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_previewFrameFactory->create() failed", __FUNCTION__, __LINE__); |
| goto err; |
| } |
| #endif |
| CLOGD("DEBUG(%s):FrameFactory(previewFrameFactory) created", __FUNCTION__); |
| } |
| |
| #ifdef CAMERA_FAST_ENTRANCE_V1 |
| if (m_fastEntrance == false) |
| #endif /* CAMERA_FAST_ENTRANCE_V1 */ |
| { |
| #ifdef USE_QOS_SETTING |
| ret = m_previewFrameFactory->setControl(V4L2_CID_IS_DVFS_CLUSTER1, BIG_CORE_MAX_LOCK, PIPE_3AA); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):V4L2_CID_IS_DVFS_CLUSTER1 setControl fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| #endif |
| |
| if (m_exynosCameraParameters->getUseFastenAeStable() == true && |
| m_exynosCameraParameters->getDualMode() == false && |
| m_exynosCameraParameters->getRecordingHint() == false && |
| m_isFirstStart == true) { |
| |
| ret = m_fastenAeStable(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_fastenAeStable() failed", __FUNCTION__, __LINE__); |
| ret = INVALID_OPERATION; |
| goto err; |
| } else { |
| skipFrameCount = 0; |
| m_exynosCameraParameters->setUseFastenAeStable(false); |
| } |
| } else if(m_exynosCameraParameters->getDualMode() == true) { |
| skipFrameCount = INITIAL_SKIP_FRAME + 2; |
| } |
| } |
| |
| #ifdef CAMERA_FAST_ENTRANCE_V1 |
| if (m_fastEntrance == true) { |
| m_waitFastenAeThreadEnd(); |
| if (m_fastenAeThreadResult < 0) { |
| CLOGE("ERR(%s[%d]):fastenAeThread exit with error", __FUNCTION__, __LINE__); |
| ret = m_fastenAeThreadResult; |
| goto err; |
| } |
| } |
| #endif |
| |
| #ifdef SET_FPS_SCENE /* This codes for 5260, Do not need other project */ |
| struct camera2_shot_ext *initMetaData = new struct camera2_shot_ext; |
| if (initMetaData != NULL) { |
| m_exynosCameraParameters->duplicateCtrlMetadata(initMetaData); |
| |
| ret = m_previewFrameFactory->setControl(V4L2_CID_IS_MIN_TARGET_FPS, initMetaData->shot.ctl.aa.aeTargetFpsRange[0], PIPE_FLITE); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):FLITE setControl fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| |
| ret = m_previewFrameFactory->setControl(V4L2_CID_IS_MAX_TARGET_FPS, initMetaData->shot.ctl.aa.aeTargetFpsRange[1], PIPE_FLITE); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):FLITE setControl fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| |
| ret = m_previewFrameFactory->setControl(V4L2_CID_IS_SCENE_MODE, initMetaData->shot.ctl.aa.sceneMode, PIPE_FLITE); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):FLITE setControl fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| delete initMetaData; |
| initMetaData = NULL; |
| } else { |
| CLOGE("ERR(%s[%d]):initMetaData is NULL", __FUNCTION__, __LINE__); |
| } |
| #elif SET_FPS_FRONTCAM |
| if (m_exynosCameraParameters->getCameraId() == CAMERA_ID_FRONT) { |
| struct camera2_shot_ext *initMetaData = new struct camera2_shot_ext; |
| if (initMetaData != NULL) { |
| m_exynosCameraParameters->duplicateCtrlMetadata(initMetaData); |
| CLOGD("(%s:[%d]) : setControl for Frame Range.", __FUNCTION__, __LINE__); |
| |
| ret = m_previewFrameFactory->setControl(V4L2_CID_IS_MIN_TARGET_FPS, initMetaData->shot.ctl.aa.aeTargetFpsRange[0], PIPE_FLITE_FRONT); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):FLITE setControl fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| |
| ret = m_previewFrameFactory->setControl(V4L2_CID_IS_MAX_TARGET_FPS, initMetaData->shot.ctl.aa.aeTargetFpsRange[1], PIPE_FLITE_FRONT); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):FLITE setControl fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| |
| delete initMetaData; |
| initMetaData = NULL; |
| } else { |
| CLOGE("ERR(%s[%d]):initMetaData is NULL", __FUNCTION__, __LINE__); |
| } |
| } |
| #endif |
| #ifdef USE_FADE_IN_ENTRANCE |
| if (m_exynosCameraParameters->getFirstEntrance() == true) { |
| /* Fade In/Out */ |
| m_exynosCameraParameters->setFrameSkipCount(0); |
| ret = m_previewFrameFactory->setControl(V4L2_CID_CAMERA_FADE_IN, 1, PIPE_FLITE); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):FLITE setControl fail(V4L2_CID_CAMERA_FADE_IN), ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| } else { |
| /* Skip Frame */ |
| m_exynosCameraParameters->setFrameSkipCount(skipFrameCount); |
| ret = m_previewFrameFactory->setControl(V4L2_CID_CAMERA_FADE_IN, 0, PIPE_FLITE); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):FLITE setControl fail(V4L2_CID_CAMERA_FADE_IN), ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| } |
| #else |
| #ifdef CAMERA_FAST_ENTRANCE_V1 |
| if (m_fastEntrance == false) |
| #endif |
| { |
| m_exynosCameraParameters->setFrameSkipCount(skipFrameCount); |
| } |
| #endif |
| |
| #ifdef CAMERA_FAST_ENTRANCE_V1 |
| if (m_fastEntrance == false) |
| #endif |
| { |
| m_setBuffersThread->join(); |
| } |
| |
| if (m_isSuccessedBufferAllocation == false) { |
| CLOGE("ERR(%s[%d]):m_setBuffersThread() failed", __FUNCTION__, __LINE__); |
| goto err; |
| } |
| |
| ret = m_startPreviewInternal(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_startPreviewInternal() failed", __FUNCTION__, __LINE__); |
| goto err; |
| } |
| |
| if (m_exynosCameraParameters->isReprocessing() == true) { |
| #ifdef START_PICTURE_THREAD |
| #if !defined(USE_SNAPSHOT_ON_UHD_RECORDING) |
| if (!m_exynosCameraParameters->getEffectRecordingHint() && |
| !m_exynosCameraParameters->getDualRecordingHint() && |
| !m_exynosCameraParameters->getUHDRecordingMode()) |
| #endif |
| { |
| m_startPictureInternalThread->run(PRIORITY_DEFAULT); |
| } |
| #endif |
| } else { |
| m_pictureFrameFactory = m_previewFrameFactory; |
| CLOGD("DEBUG(%s[%d]):FrameFactory(pictureFrameFactory) created", __FUNCTION__, __LINE__); |
| |
| /* |
| * Make remained frameFactory here. |
| * in case of SCC capture, make here. |
| */ |
| m_framefactoryThread->run(); |
| } |
| |
| #if !defined(USE_SNAPSHOT_ON_UHD_RECORDING) |
| if (!m_exynosCameraParameters->getEffectRecordingHint() && |
| !m_exynosCameraParameters->getDualRecordingHint() && |
| !m_exynosCameraParameters->getUHDRecordingMode()) |
| #endif |
| { |
| m_startPictureBufferThread->run(PRIORITY_DEFAULT); |
| } |
| |
| if (m_previewWindow != NULL) |
| m_previewWindow->set_timestamp(m_previewWindow, systemTime(SYSTEM_TIME_MONOTONIC)); |
| |
| #ifdef RAWDUMP_CAPTURE |
| m_mainSetupQThread[INDEX(PIPE_FLITE)]->run(PRIORITY_URGENT_DISPLAY); |
| m_mainSetupQThread[INDEX(PIPE_3AA)]->run(PRIORITY_URGENT_DISPLAY); |
| #else |
| /* setup frame thread */ |
| if (m_exynosCameraParameters->getDualMode() == true && getCameraId() == CAMERA_ID_FRONT) { |
| CLOGD("DEBUG(%s[%d]):setupThread Thread start pipeId(%d)", __FUNCTION__, __LINE__, PIPE_FLITE); |
| m_mainSetupQThread[INDEX(PIPE_FLITE)]->run(PRIORITY_URGENT_DISPLAY); |
| } else { |
| switch (m_exynosCameraParameters->getReprocessingBayerMode()) { |
| case REPROCESSING_BAYER_MODE_PURE_ALWAYS_ON: |
| m_mainSetupQ[INDEX(PIPE_FLITE)]->setup(NULL); |
| CLOGD("DEBUG(%s[%d]):setupThread Thread start pipeId(%d)", __FUNCTION__, __LINE__, PIPE_FLITE); |
| m_mainSetupQThread[INDEX(PIPE_FLITE)]->run(PRIORITY_URGENT_DISPLAY); |
| break; |
| case REPROCESSING_BAYER_MODE_PURE_DYNAMIC: |
| CLOGD("DEBUG(%s[%d]):setupThread with List pipeId(%d)", __FUNCTION__, __LINE__, PIPE_FLITE); |
| m_mainSetupQ[INDEX(PIPE_FLITE)]->setup(m_mainSetupQThread[INDEX(PIPE_FLITE)]); |
| break; |
| default: |
| CLOGI("INFO(%s[%d]):setupThread not started pipeID(%d)", __FUNCTION__, __LINE__, PIPE_FLITE); |
| break; |
| } |
| CLOGD("DEBUG(%s[%d]):setupThread Thread start pipeId(%d)", __FUNCTION__, __LINE__, PIPE_3AA); |
| m_mainSetupQThread[INDEX(PIPE_3AA)]->run(PRIORITY_URGENT_DISPLAY); |
| } |
| #endif |
| |
| #ifdef SAMSUNG_DNG |
| if (m_exynosCameraParameters->getDNGCaptureModeOn()) { |
| CLOGD("[DNG](%s[%d]):setupThread with List pipeId(%d)", __FUNCTION__, __LINE__, PIPE_FLITE); |
| m_mainSetupQ[INDEX(PIPE_FLITE)]->setup(m_mainSetupQThread[INDEX(PIPE_FLITE)]); |
| } |
| #endif |
| |
| if (m_facedetectThread->isRunning() == false) |
| m_facedetectThread->run(); |
| |
| m_previewThread->run(PRIORITY_DISPLAY); |
| m_mainThread->run(PRIORITY_DEFAULT); |
| if(m_exynosCameraParameters->getCameraId() == CAMERA_ID_BACK) { |
| m_autoFocusContinousThread->run(PRIORITY_DEFAULT); |
| } |
| m_monitorThread->run(PRIORITY_DEFAULT); |
| |
| if (m_exynosCameraParameters->getZoomPreviewWIthScaler() == true) { |
| CLOGD("DEBUG(%s[%d]):ZoomPreview with Scaler Thread start", __FUNCTION__, __LINE__); |
| m_zoomPreviwWithCscThread->run(PRIORITY_DEFAULT); |
| } |
| |
| if ((m_exynosCameraParameters->getHighResolutionCallbackMode() == true) && |
| (m_highResolutionCallbackRunning == false)) { |
| CLOGD("DEBUG(%s[%d]):High resolution preview callback start", __FUNCTION__, __LINE__); |
| if (skipFrameCount > 0) |
| m_skipReprocessing = true; |
| m_highResolutionCallbackRunning = true; |
| if (m_exynosCameraParameters->isReprocessing() == true) { |
| m_startPictureInternalThread->run(PRIORITY_DEFAULT); |
| m_startPictureInternalThread->join(); |
| } |
| m_prePictureThread->run(PRIORITY_DEFAULT); |
| } |
| |
| /* FD-AE is always on */ |
| #ifdef USE_FD_AE |
| m_startFaceDetection(m_exynosCameraParameters->getFaceDetectionMode()); |
| #endif |
| |
| if (m_exynosCameraParameters->getUseFastenAeStable() == true && |
| m_exynosCameraParameters->getCameraId() == CAMERA_ID_BACK && |
| m_exynosCameraParameters->getDualMode() == false && |
| m_exynosCameraParameters->getRecordingHint() == false && |
| m_isFirstStart == true) { |
| /* AF mode is setted as INFINITY in fastenAE, and we should update that mode */ |
| m_exynosCameraActivityControl->setAutoFocusMode(FOCUS_MODE_INFINITY); |
| |
| m_exynosCameraParameters->setUseFastenAeStable(false); |
| m_exynosCameraActivityControl->setAutoFocusMode(m_exynosCameraParameters->getFocusMode()); |
| m_isFirstStart = false; |
| m_exynosCameraParameters->setIsFirstStartFlag(m_isFirstStart); |
| } |
| } |
| |
| #ifdef BURST_CAPTURE |
| m_burstInitFirst = true; |
| #endif |
| |
| #ifdef SAMSUNG_JQ |
| { |
| int HwPreviewW = 0, HwPreviewH = 0; |
| UniPluginBufferData_t pluginData; |
| |
| m_exynosCameraParameters->getHwPreviewSize(&HwPreviewW, &HwPreviewH); |
| memset(&pluginData, 0, sizeof(UniPluginBufferData_t)); |
| pluginData.InWidth = HwPreviewW; |
| pluginData.InHeight = HwPreviewH; |
| pluginData.InFormat = UNI_PLUGIN_FORMAT_NV21; |
| |
| if(m_JQpluginHandle != NULL) { |
| ret = uni_plugin_set(m_JQpluginHandle, |
| JPEG_QTABLE_PLUGIN_NAME, UNI_PLUGIN_INDEX_BUFFER_INFO, &pluginData); |
| if(ret < 0) { |
| CLOGE("[JQ](%s[%d]): Plugin set(UNI_PLUGIN_INDEX_BUFFER_INFO) failed!!", __FUNCTION__, __LINE__); |
| } |
| ret = uni_plugin_init(m_JQpluginHandle); |
| if(ret < 0) { |
| CLOGE("[JQ](%s[%d]): Plugin init failed!!", __FUNCTION__, __LINE__); |
| } |
| } |
| } |
| #endif |
| |
| #ifdef SAMSUNG_DEBLUR |
| if(m_DeblurpluginHandle != NULL) { |
| ret = uni_plugin_init(m_DeblurpluginHandle); |
| if(ret < 0) { |
| CLOGE("[Deblur](%s[%d]): Deblur plugin init failed!!", __FUNCTION__, __LINE__); |
| } |
| } |
| #endif |
| |
| #ifdef CAMERA_FAST_ENTRANCE_V1 |
| m_fastEntrance = false; |
| #endif |
| |
| return NO_ERROR; |
| |
| err: |
| |
| #ifdef SAMSUNG_COMPANION |
| if(m_use_companion == true) { |
| m_waitCompanionThreadEnd(); |
| } |
| #endif |
| #if defined(SAMSUNG_EEPROM) |
| if ((m_use_companion == false) && (isEEprom(getCameraId()) == true)) { |
| if (m_eepromThread != NULL) { |
| m_eepromThread->join(); |
| } else { |
| CLOGD("DEBUG(%s): eepromThread is NULL.", __FUNCTION__); |
| } |
| } |
| #endif |
| |
| #ifdef CAMERA_FAST_ENTRANCE_V1 |
| if (m_fastEntrance == true) { |
| m_waitFastenAeThreadEnd(); |
| } |
| |
| m_fastEntrance = false; |
| #endif |
| |
| /* frame manager stop */ |
| m_frameMgr->stop(); |
| |
| m_setBuffersThread->join(); |
| |
| m_releaseBuffers(); |
| |
| #ifdef SAMSUNG_SENSOR_LISTENER |
| if (m_sensorListenerThread != NULL) { |
| m_sensorListenerThread->requestExitAndWait(); |
| } |
| |
| #ifdef SAMSUNG_HRM |
| if(m_uv_rayHandle != NULL) { |
| m_exynosCameraParameters->m_setHRM_Hint(false); |
| sensor_listener_disable_sensor(m_uv_rayHandle, ST_UV_RAY); |
| sensor_listener_unload(&m_uv_rayHandle); |
| m_uv_rayHandle = NULL; |
| } |
| #endif |
| |
| #ifdef SAMSUNG_LIGHT_IR |
| if(m_light_irHandle != NULL) { |
| m_exynosCameraParameters->m_setLight_IR_Hint(false); |
| sensor_listener_disable_sensor(m_light_irHandle, ST_LIGHT_IR); |
| sensor_listener_unload(&m_light_irHandle); |
| m_light_irHandle = NULL; |
| } |
| #endif |
| |
| #ifdef SAMSUNG_GYRO |
| if(m_gyroHandle != NULL) { |
| m_exynosCameraParameters->m_setGyroHint(false); |
| sensor_listener_disable_sensor(m_gyroHandle, ST_GYROSCOPE); |
| sensor_listener_unload(&m_gyroHandle); |
| m_gyroHandle = NULL; |
| } |
| #endif |
| #endif /* SAMSUNG_SENSOR_LISTENER */ |
| |
| return ret; |
| } |
| |
| void ExynosCamera::stopPreview() |
| { |
| CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__); |
| int ret = 0; |
| |
| ExynosCameraActivityFlash *m_flashMgr = m_exynosCameraActivityControl->getFlashMgr(); |
| ExynosCameraActivityAutofocus *autoFocusMgr = m_exynosCameraActivityControl->getAutoFocusMgr(); |
| ExynosCameraFrame *frame = NULL; |
| |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| m_clearOneSecondBurst(false); |
| #endif |
| |
| #ifdef LLS_CAPTURE |
| m_exynosCameraParameters->setLLSOn(false); |
| #endif |
| |
| m_flagLLSStart = false; |
| |
| #ifdef CAMERA_FAST_ENTRANCE_V1 |
| if (m_fastenAeThread != NULL) { |
| CLOGI("INFO(%s[%d]): wait m_fastenAeThread", __FUNCTION__, __LINE__); |
| m_fastenAeThread->requestExitAndWait(); |
| CLOGI("INFO(%s[%d]): wait m_fastenAeThread end", __FUNCTION__, __LINE__); |
| } else { |
| CLOGI("INFO(%s[%d]):m_fastenAeThread is NULL", __FUNCTION__, __LINE__); |
| } |
| #endif |
| |
| #ifdef SAMSUNG_COMPANION |
| if(m_use_companion == true) { |
| if (m_companionThread != NULL) { |
| CLOGI("INFO(%s[%d]): wait m_companionThread", __FUNCTION__, __LINE__); |
| m_companionThread->requestExitAndWait(); |
| CLOGI("INFO(%s[%d]): wait m_companionThread end", __FUNCTION__, __LINE__); |
| } else { |
| CLOGI("INFO(%s[%d]): m_companionThread is NULL", __FUNCTION__, __LINE__); |
| } |
| } |
| #endif |
| |
| if (m_previewEnabled == false) { |
| CLOGD("DEBUG(%s[%d]): preview is not enabled", __FUNCTION__, __LINE__); |
| return; |
| } |
| |
| m_stopLongExposure = true; |
| |
| if (m_pictureEnabled == true) { |
| CLOGW("WARN(%s[%d]):m_pictureEnabled == true (picture is not finished)", __FUNCTION__, __LINE__); |
| int retry = 0; |
| do { |
| usleep(WAITING_TIME); |
| retry++; |
| } while(m_pictureEnabled == true && retry < (TOTAL_WAITING_TIME/WAITING_TIME)); |
| CLOGW("WARN(%s[%d]):wait (%d)msec (because, picture is not finished)", __FUNCTION__, __LINE__, WAITING_TIME * retry / 1000); |
| } |
| |
| m_exynosCameraParameters->setIsThumbnailCallbackOn(false); |
| |
| if (m_exynosCameraParameters->getVisionMode() == true) { |
| m_frameFactoryQ->release(); |
| m_visionThread->requestExitAndWait(); |
| ret = m_stopVisionInternal(); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):m_stopVisionInternal fail", __FUNCTION__, __LINE__); |
| } else { |
| #ifdef USE_QOS_SETTING |
| if (m_previewFrameFactory == NULL) { |
| CLOGW("WARN(%s[%d]):m_previewFrameFactory is NULL. so, skip setControl(V4L2_CID_IS_DVFS_CLUSTER1)", __FUNCTION__, __LINE__); |
| } else { |
| ret = m_previewFrameFactory->setControl(V4L2_CID_IS_DVFS_CLUSTER1, 0, PIPE_3AA); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):V4L2_CID_IS_DVFS_CLUSTER1 setControl fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| } |
| #endif |
| m_startPictureInternalThread->join(); |
| |
| /* release about frameFactory */ |
| m_framefactoryThread->stop(); |
| m_frameFactoryQ->sendCmd(WAKE_UP); |
| m_framefactoryThread->requestExitAndWait(); |
| m_frameFactoryQ->release(); |
| |
| m_startPictureBufferThread->join(); |
| |
| m_autoFocusRunning = false; |
| m_exynosCameraActivityControl->cancelAutoFocus(); |
| |
| CLOGD("DEBUG(%s[%d]): (%d, %d)", __FUNCTION__, __LINE__, m_flashMgr->getNeedCaptureFlash(), m_pictureEnabled); |
| if (m_flashMgr->getNeedCaptureFlash() == true && m_pictureEnabled == true) { |
| CLOGD("DEBUG(%s[%d]): force flash off", __FUNCTION__, __LINE__); |
| m_exynosCameraActivityControl->cancelFlash(); |
| autoFocusMgr->stopAutofocus(); |
| m_isTryStopFlash = true; |
| /* m_exitAutoFocusThread = true; */ |
| } |
| |
| /* Wait the end of the autoFocus Thread in order to the autofocus and the pre-flash is completed.*/ |
| m_autoFocusLock.lock(); |
| m_exitAutoFocusThread = true; |
| m_autoFocusLock.unlock(); |
| |
| int flashMode = AA_FLASHMODE_OFF; |
| int waitingTime = FLASH_OFF_MAX_WATING_TIME / TOTAL_FLASH_WATING_COUNT; /* Max waiting time: 500ms, Count:10, Waiting time: 50ms */ |
| |
| flashMode = m_flashMgr->getFlashStatus(); |
| if ((flashMode == AA_FLASHMODE_ON_ALWAYS) || (m_flashMgr->getNeedFlashOffDelay() == true)) { |
| int i = 0; |
| CLOGD("DEBUG(%s[%d]): flash torch was enabled", __FUNCTION__, __LINE__); |
| |
| m_exynosCameraParameters->setFrameSkipCount(100); |
| do { |
| if (m_flashMgr->checkFlashOff() == false) { |
| usleep(waitingTime); |
| } else { |
| CLOGD("DEBUG(%s[%d]):turn off the flash torch.(%d)", __FUNCTION__, __LINE__, i); |
| |
| flashMode = m_flashMgr->getFlashStatus(); |
| if (flashMode == AA_FLASHMODE_OFF || flashMode == AA_FLASHMODE_CANCEL) |
| { |
| m_flashMgr->setFlashStep(ExynosCameraActivityFlash::FLASH_STEP_OFF); |
| } |
| usleep(waitingTime); |
| break; |
| } |
| } while(++i < TOTAL_FLASH_WATING_COUNT); |
| |
| if (i >= TOTAL_FLASH_WATING_COUNT) { |
| CLOGD("DEBUG(%s[%d]):timeOut-flashMode(%d),checkFlashOff(%d)", |
| __FUNCTION__, __LINE__, flashMode, m_flashMgr->checkFlashOff()); |
| } |
| } else if (m_isTryStopFlash == true) { |
| usleep(waitingTime*3); /* 150ms */ |
| m_flashMgr->setFlashStep(ExynosCameraActivityFlash::FLASH_STEP_OFF); |
| } |
| |
| m_flashMgr->setNeedFlashOffDelay(false); |
| |
| if (m_previewFrameFactory == NULL) { |
| CLOGW("WARN(%s[%d]):m_previewFrameFactory is NULL.", __FUNCTION__, __LINE__); |
| } else { |
| m_previewFrameFactory->setStopFlag(); |
| } |
| if (m_exynosCameraParameters->isReprocessing() == true && m_reprocessingFrameFactory->isCreated() == true) |
| m_reprocessingFrameFactory->setStopFlag(); |
| m_flagThreadStop = true; |
| |
| m_takePictureCounter.clearCount(); |
| m_reprocessingCounter.clearCount(); |
| m_pictureCounter.clearCount(); |
| m_jpegCounter.clearCount(); |
| m_captureSelector->cancelPicture(); |
| |
| if ((m_exynosCameraParameters->getHighResolutionCallbackMode() == true) && |
| (m_highResolutionCallbackRunning == true)) { |
| m_skipReprocessing = false; |
| m_highResolutionCallbackRunning = false; |
| CLOGD("DEBUG(%s[%d]):High resolution preview callback stop", __FUNCTION__, __LINE__); |
| if(getCameraId() == CAMERA_ID_FRONT) { |
| m_sccCaptureSelector->cancelPicture(); |
| m_sccCaptureSelector->wakeupQ(); |
| CLOGD("DEBUG(%s[%d]):High resolution m_sccCaptureSelector cancel", __FUNCTION__, __LINE__); |
| } |
| |
| m_prePictureThread->requestExitAndWait(); |
| m_highResolutionCallbackQ->release(); |
| } |
| |
| ret = m_stopPictureInternal(); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):m_stopPictureInternal fail", __FUNCTION__, __LINE__); |
| |
| m_exynosCameraActivityControl->stopAutoFocus(); |
| m_autoFocusThread->requestExitAndWait(); |
| |
| if (m_previewQ != NULL) { |
| m_previewQ->sendCmd(WAKE_UP); |
| } else { |
| CLOGI("INFO(%s[%d]): m_previewQ is NULL", __FUNCTION__, __LINE__); |
| } |
| |
| m_zoomPreviwWithCscThread->stop(); |
| m_zoomPreviwWithCscQ->sendCmd(WAKE_UP); |
| m_zoomPreviwWithCscThread->requestExitAndWait(); |
| |
| |
| m_pipeFrameDoneQ->sendCmd(WAKE_UP); |
| m_mainThread->requestExitAndWait(); |
| m_monitorThread->requestExitAndWait(); |
| |
| m_shutterCallbackThread->requestExitAndWait(); |
| |
| m_previewThread->stop(); |
| if (m_previewQ != NULL) { |
| m_previewQ->sendCmd(WAKE_UP); |
| } |
| m_previewThread->requestExitAndWait(); |
| |
| if (m_exynosCameraParameters->isFlite3aaOtf() == true) { |
| m_mainSetupQThread[INDEX(PIPE_FLITE)]->stop(); |
| m_mainSetupQ[INDEX(PIPE_FLITE)]->sendCmd(WAKE_UP); |
| m_mainSetupQThread[INDEX(PIPE_FLITE)]->requestExitAndWait(); |
| |
| if (m_mainSetupQThread[INDEX(PIPE_3AC)] != NULL) { |
| m_mainSetupQThread[INDEX(PIPE_3AC)]->stop(); |
| m_mainSetupQ[INDEX(PIPE_3AC)]->sendCmd(WAKE_UP); |
| m_mainSetupQThread[INDEX(PIPE_3AC)]->requestExitAndWait(); |
| } |
| |
| m_mainSetupQThread[INDEX(PIPE_3AA)]->stop(); |
| m_mainSetupQ[INDEX(PIPE_3AA)]->sendCmd(WAKE_UP); |
| m_mainSetupQThread[INDEX(PIPE_3AA)]->requestExitAndWait(); |
| |
| if (m_mainSetupQThread[INDEX(PIPE_ISP)] != NULL) { |
| m_mainSetupQThread[INDEX(PIPE_ISP)]->stop(); |
| m_mainSetupQ[INDEX(PIPE_ISP)]->sendCmd(WAKE_UP); |
| m_mainSetupQThread[INDEX(PIPE_ISP)]->requestExitAndWait(); |
| } |
| |
| /* Comment out, because it included ISP */ |
| /* m_mainSetupQThread[INDEX(PIPE_SCP)]->requestExitAndWait(); */ |
| } else { |
| if (m_mainSetupQThread[INDEX(PIPE_FLITE)] != NULL) { |
| m_mainSetupQThread[INDEX(PIPE_FLITE)]->stop(); |
| m_mainSetupQ[INDEX(PIPE_FLITE)]->sendCmd(WAKE_UP); |
| m_mainSetupQThread[INDEX(PIPE_FLITE)]->requestExitAndWait(); |
| } |
| } |
| |
| m_autoFocusContinousThread->stop(); |
| m_autoFocusContinousQ.sendCmd(WAKE_UP); |
| m_autoFocusContinousThread->requestExitAndWait(); |
| m_autoFocusContinousQ.release(); |
| |
| m_facedetectThread->stop(); |
| m_facedetectQ->sendCmd(WAKE_UP); |
| m_facedetectThread->requestExitAndWait(); |
| while (m_facedetectQ->getSizeOfProcessQ()) { |
| m_facedetectQ->popProcessQ(&frame); |
| frame->decRef(); |
| m_frameMgr->deleteFrame(frame); |
| frame = NULL; |
| } |
| |
| if (m_previewQ != NULL) { |
| m_clearList(m_previewQ); |
| } |
| |
| if (m_zoomPreviwWithCscQ != NULL) { |
| m_zoomPreviwWithCscQ->release(); |
| } |
| |
| if (m_previewCallbackGscFrameDoneQ != NULL) { |
| m_clearList(m_previewCallbackGscFrameDoneQ); |
| } |
| |
| for(int i = 0 ; i < MAX_NUM_PIPES ; i++ ) { |
| m_clearList(m_mainSetupQ[i]); |
| } |
| |
| ret = m_stopPreviewInternal(); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):m_stopPreviewInternal fail", __FUNCTION__, __LINE__); |
| |
| #ifdef SUPPORT_SW_VDIS |
| if(m_swVDIS_Mode) { |
| m_swVDIS_deinit(); |
| for (int bufIndex = 0; bufIndex < NUM_VDIS_BUFFERS; bufIndex++) { |
| m_putBuffers(m_swVDIS_BufferMgr, bufIndex); |
| } |
| if (m_swVDIS_BufferMgr != NULL) { |
| m_swVDIS_BufferMgr->deinit(); |
| } |
| |
| if (m_previewWindow != NULL) |
| m_previewWindow->set_crop(m_previewWindow, 0, 0, 0, 0); |
| |
| if(m_exynosCameraParameters->increaseMaxBufferOfPreview()) { |
| m_exynosCameraParameters->setPreviewBufferCount(NUM_PREVIEW_BUFFERS + NUM_PREVIEW_SPARE_BUFFERS); |
| m_exynosconfig->current->bufInfo.num_preview_buffers = NUM_PREVIEW_BUFFERS + NUM_PREVIEW_SPARE_BUFFERS; |
| VDIS_LOG("VDIS_HAL: Preview Buffer Count Change to %d", NUM_PREVIEW_BUFFERS + NUM_PREVIEW_SPARE_BUFFERS); |
| } else { |
| m_exynosCameraParameters->setPreviewBufferCount(NUM_PREVIEW_BUFFERS); |
| m_exynosconfig->current->bufInfo.num_preview_buffers = NUM_PREVIEW_BUFFERS; |
| VDIS_LOG("VDIS_HAL: Preview Buffer Count Change to %d", NUM_PREVIEW_BUFFERS); |
| } |
| } |
| #endif /*SUPPORT_SW_VDIS*/ |
| #ifdef USE_FASTMOTION_CROP |
| if(m_exynosCameraParameters->getShotMode() == SHOT_MODE_FASTMOTION) { |
| if (m_previewWindow != NULL) { |
| m_previewWindow->set_crop(m_previewWindow, 0, 0, 0, 0); |
| } |
| } |
| #endif /* USE_FASTMOTION_CROP */ |
| } |
| |
| /* skip to free and reallocate buffers : flite / 3aa / isp / ispReprocessing */ |
| if (m_bayerBufferMgr != NULL) { |
| m_bayerBufferMgr->resetBuffers(); |
| } |
| #ifdef SAMSUNG_DNG |
| if (m_fliteBufferMgr != NULL) { |
| m_fliteBufferMgr->resetBuffers(); |
| } |
| #endif |
| if (m_3aaBufferMgr != NULL) { |
| m_3aaBufferMgr->resetBuffers(); |
| } |
| if (m_ispBufferMgr != NULL) { |
| #if defined (USE_ISP_BUFFER_SIZE_TO_BDS) |
| m_ispBufferMgr->deinit(); |
| #else |
| m_ispBufferMgr->resetBuffers(); |
| #endif |
| } |
| if (m_hwDisBufferMgr != NULL) { |
| m_hwDisBufferMgr->resetBuffers(); |
| } |
| |
| /* realloc reprocessing buffer for change burst panorama <-> normal mode */ |
| if (m_ispReprocessingBufferMgr != NULL) { |
| m_ispReprocessingBufferMgr->resetBuffers(); |
| } |
| if (m_sccReprocessingBufferMgr != NULL) { |
| m_sccReprocessingBufferMgr->resetBuffers(); |
| } |
| |
| /* realloc callback buffers */ |
| if (m_scpBufferMgr != NULL) { |
| m_scpBufferMgr->deinit(); |
| m_scpBufferMgr->setBufferCount(0); |
| } |
| if (m_zoomScalerBufferMgr != NULL) { |
| m_zoomScalerBufferMgr->deinit(); |
| } |
| if (m_sccBufferMgr != NULL) { |
| m_sccBufferMgr->resetBuffers(); |
| } |
| if (m_gscBufferMgr != NULL) { |
| m_gscBufferMgr->resetBuffers(); |
| } |
| |
| if (m_postPictureGscBufferMgr != NULL) { |
| m_postPictureGscBufferMgr->deinit(); |
| } |
| |
| if (m_thumbnailGscBufferMgr != NULL) { |
| m_thumbnailGscBufferMgr->deinit(); |
| } |
| |
| #ifdef SAMSUNG_LBP |
| if (m_lbpBufferMgr != NULL) { |
| m_lbpBufferMgr->deinit(); |
| } |
| #endif |
| |
| if (m_jpegBufferMgr != NULL) { |
| m_jpegBufferMgr->deinit(); |
| } |
| |
| if (m_hwDisBufferMgr != NULL) { |
| m_hwDisBufferMgr->deinit(); |
| } |
| |
| if (m_recordingBufferMgr != NULL) { |
| m_recordingBufferMgr->deinit(); |
| } |
| if (m_previewCallbackBufferMgr != NULL) { |
| m_previewCallbackBufferMgr->deinit(); |
| } |
| if (m_highResolutionCallbackBufferMgr != NULL) { |
| m_highResolutionCallbackBufferMgr->deinit(); |
| } |
| if (m_captureSelector != NULL) { |
| m_captureSelector->release(); |
| } |
| if (m_sccCaptureSelector != NULL) { |
| m_sccCaptureSelector->release(); |
| } |
| |
| #if 0 |
| /* skip to free and reallocate buffers : flite / 3aa / isp / ispReprocessing */ |
| CLOGE(" m_setBuffers free all buffers"); |
| if (m_bayerBufferMgr != NULL) { |
| m_bayerBufferMgr->deinit(); |
| } |
| if (m_3aaBufferMgr != NULL) { |
| m_3aaBufferMgr->deinit(); |
| } |
| if (m_ispBufferMgr != NULL) { |
| m_ispBufferMgr->deinit(); |
| } |
| if (m_hwDisBufferMgr != NULL) { |
| m_hwDisBufferMgr->deinit(); |
| } |
| #endif |
| /* frame manager stop */ |
| m_frameMgr->stop(); |
| m_frameMgr->deleteAllFrame(); |
| |
| |
| m_reprocessingCounter.clearCount(); |
| m_pictureCounter.clearCount(); |
| |
| m_hdrSkipedFcount = 0; |
| m_dynamicSccCount = 0; |
| |
| /* HACK Reset Preview Flag*/ |
| m_resetPreview = false; |
| |
| m_isTryStopFlash= false; |
| m_exitAutoFocusThread = false; |
| m_isNeedAllocPictureBuffer = false; |
| |
| if (m_fdCallbackHeap != NULL) { |
| m_fdCallbackHeap->release(m_fdCallbackHeap); |
| m_fdCallbackHeap = NULL; |
| } |
| |
| #ifdef SR_CAPTURE |
| if (m_srCallbackHeap != NULL) { |
| m_srCallbackHeap->release(m_srCallbackHeap); |
| m_srCallbackHeap = NULL; |
| } |
| #endif |
| |
| m_burstInitFirst = false; |
| |
| #ifdef SAMSUNG_JQ |
| if(m_JQpluginHandle != NULL) { |
| ret = uni_plugin_deinit(m_JQpluginHandle); |
| if(ret < 0) { |
| CLOGE("[JQ](%s[%d]): Plugin deinit failed!!", __FUNCTION__, __LINE__); |
| } |
| } |
| #endif |
| |
| #ifdef SAMSUNG_DEBLUR |
| if(m_DeblurpluginHandle != NULL) { |
| ret = uni_plugin_deinit(m_DeblurpluginHandle); |
| if(ret < 0) { |
| CLOGE("[Deblur](%s[%d]): Deblur Plugin deinit failed!!", __FUNCTION__, __LINE__); |
| } |
| } |
| #endif |
| |
| #ifdef SAMSUNG_DOF |
| if(m_lensmoveCount) { |
| CLOGW("[DOF][%s][%d] Out-focus shot parameter is not reset. Reset here forcely!!: %d", |
| __FUNCTION__, __LINE__, m_lensmoveCount); |
| ExynosCameraActivityAutofocus *autoFocusMgr = m_exynosCameraActivityControl->getAutoFocusMgr(); |
| autoFocusMgr->setStartLensMove(false); |
| m_lensmoveCount = 0; |
| m_exynosCameraParameters->setMoveLensCount(m_lensmoveCount); |
| m_exynosCameraParameters->setMoveLensTotal(m_lensmoveCount); |
| } |
| #endif |
| |
| #ifdef SAMSUNG_SENSOR_LISTENER |
| if (m_sensorListenerThread != NULL) { |
| m_sensorListenerThread->requestExitAndWait(); |
| } |
| |
| #ifdef SAMSUNG_HRM |
| if(m_uv_rayHandle != NULL) { |
| m_exynosCameraParameters->m_setHRM_Hint(false); |
| } |
| #endif |
| |
| #ifdef SAMSUNG_LIGHT_IR |
| if(m_light_irHandle != NULL) { |
| m_exynosCameraParameters->m_setLight_IR_Hint(false); |
| } |
| #endif |
| |
| #ifdef SAMSUNG_GYRO |
| if(m_gyroHandle != NULL) { |
| m_exynosCameraParameters->m_setGyroHint(false); |
| } |
| #endif |
| #endif /* SAMSUNG_SENSOR_LISTENER */ |
| |
| #ifdef FORCE_RESET_MULTI_FRAME_FACTORY |
| /* |
| * HACK |
| * This is force-reset frameFactory adn companion |
| */ |
| m_deinitFrameFactory(); |
| |
| /* |
| * close companion : other node all closed in m_deinitFrameFactory() |
| * so, we close also companion |
| */ |
| if (m_stopCompanion() != NO_ERROR) |
| CLOGE("ERR(%s[%d]):m_stopCompanion() fail", __FUNCTION__, __LINE__); |
| |
| m_initFrameFactory(); |
| #endif |
| |
| #ifdef CAMERA_FAST_ENTRANCE_V1 |
| m_fastEntrance = false; |
| #endif |
| } |
| |
| bool ExynosCamera::previewEnabled() |
| { |
| CLOGI("INFO(%s[%d]):m_previewEnabled=%d", |
| __FUNCTION__, __LINE__, (int)m_previewEnabled); |
| |
| /* in scalable mode, we should controll out state */ |
| if (m_exynosCameraParameters != NULL && |
| (m_exynosCameraParameters->getScalableSensorMode() == true) && |
| (m_scalableSensorMgr.getMode() == EXYNOS_CAMERA_SCALABLE_CHANGING)) |
| return true; |
| else |
| return m_previewEnabled; |
| } |
| |
| status_t ExynosCamera::storeMetaDataInBuffers( __unused bool enable) |
| { |
| CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__); |
| |
| return OK; |
| } |
| |
| status_t ExynosCamera::startRecording() |
| { |
| CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__); |
| #ifdef SAMSUNG_HLV |
| int curVideoW = 0, curVideoH = 0; |
| uint32_t curMinFps = 0, curMaxFps = 0; |
| #endif |
| if (m_exynosCameraParameters != NULL) { |
| if (m_exynosCameraParameters->getVisionMode() == true) { |
| CLOGW("WRN(%s[%d]): Vision mode does not support", __FUNCTION__, __LINE__); |
| android_printAssert(NULL, LOG_TAG, "Cannot support this operation"); |
| |
| return INVALID_OPERATION; |
| } |
| } |
| |
| int ret = 0; |
| ExynosCameraActivityAutofocus *autoFocusMgr = m_exynosCameraActivityControl->getAutoFocusMgr(); |
| ExynosCameraActivityFlash *flashMgr = m_exynosCameraActivityControl->getFlashMgr(); |
| flashMgr->setCaptureStatus(false); |
| |
| if (m_getRecordingEnabled() == true) { |
| CLOGW("WARN(%s[%d]):m_recordingEnabled equals true", __FUNCTION__, __LINE__); |
| ret = INVALID_OPERATION; |
| goto func_exit; |
| } |
| |
| #ifdef USE_FD_AE |
| if (m_exynosCameraParameters != NULL) { |
| if (m_exynosCameraParameters->getFaceDetectionMode() == false) { |
| m_startFaceDetection(false); |
| } else { |
| /* stay current fd mode */ |
| } |
| } else { |
| CLOGW("(%s[%d]):m_exynosCameraParameters is NULL", __FUNCTION__, __LINE__); |
| return INVALID_OPERATION; |
| } |
| #endif |
| |
| |
| /* Do start recording process */ |
| ret = m_startRecordingInternal(); |
| if (ret < 0) { |
| CLOGE("ERR"); |
| return ret; |
| } |
| |
| #ifdef SAMSUNG_HLV |
| m_exynosCameraParameters->getVideoSize(&curVideoW, &curVideoH); |
| m_exynosCameraParameters->getPreviewFpsRange(&curMinFps, &curMaxFps); |
| |
| if (curVideoW <= 1920 && curVideoH <= 1080 |
| && m_HLV == NULL |
| && curMinFps <= 60 && curMaxFps <= 60 |
| && !m_exynosCameraParameters->isSWVdisMode() |
| #ifdef USE_LIVE_BROADCAST |
| && m_exynosCameraParameters->getPLBMode() == false |
| #endif |
| ) { |
| ALOGD("HLV : uni_plugin_load !"); |
| m_HLV = uni_plugin_load(HIGHLIGHT_VIDEO_PLUGIN_NAME); |
| if (m_HLV != NULL) { |
| ALOGD("HLV : uni_plugin_load success!"); |
| |
| ret = uni_plugin_init(m_HLV); |
| if (ret < 0) { |
| ALOGE("HLV : uni_plugin_init fail . Unload %s", HIGHLIGHT_VIDEO_PLUGIN_NAME); |
| |
| ret = uni_plugin_unload(&m_HLV); |
| if (ret) |
| ALOGE("HLV : uni_plug_unload failed !!"); |
| |
| m_HLV = NULL; |
| } |
| else |
| { |
| ALOGD("HLV : uni_plugin_init success!"); |
| UNI_PLUGIN_CAPTURE_STATUS value = UNI_PLUGIN_CAPTURE_STATUS_VID_REC_START; |
| ALOGD("HLV: set UNI_PLUGIN_CAPTURE_STATUS_VID_REC_START"); |
| |
| uni_plugin_set(m_HLV, |
| HIGHLIGHT_VIDEO_PLUGIN_NAME, |
| UNI_PLUGIN_INDEX_CAPTURE_STATUS, |
| &value); |
| } |
| } |
| else { |
| ALOGD("HLV : uni_plugin_load fail!"); |
| } |
| } |
| else { |
| ALOGD("HLV : Not Supported for %dx%d(%d fps) video record !", |
| curVideoW, curVideoH, curMinFps); |
| } |
| #endif |
| |
| m_lastRecordingTimeStamp = 0; |
| m_recordingStartTimeStamp = 0; |
| m_recordingFrameSkipCount = 0; |
| |
| m_setRecordingEnabled(true); |
| |
| autoFocusMgr->setRecordingHint(true); |
| flashMgr->setRecordingHint(true); |
| |
| func_exit: |
| /* wait for initial preview skip */ |
| if (m_exynosCameraParameters != NULL) { |
| int retry = 0; |
| while (m_exynosCameraParameters->getFrameSkipCount() > 0 && retry < 3) { |
| retry++; |
| usleep(33000); |
| CLOGI("INFO(%s[%d]): -OUT- (frameSkipCount:%d) (retry:%d)", __FUNCTION__, __LINE__, m_frameSkipCount, retry); |
| } |
| } |
| |
| return NO_ERROR; |
| } |
| |
| void ExynosCamera::stopRecording() |
| { |
| CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__); |
| |
| if (m_exynosCameraParameters != NULL) { |
| if (m_exynosCameraParameters->getVisionMode() == true) { |
| CLOGW("WRN(%s[%d]): Vision mode does not support", __FUNCTION__, __LINE__); |
| android_printAssert(NULL, LOG_TAG, "Cannot support this operation"); |
| |
| return; |
| } |
| } |
| |
| int ret = 0; |
| ExynosCameraActivityAutofocus *autoFocusMgr = m_exynosCameraActivityControl->getAutoFocusMgr(); |
| ExynosCameraActivityFlash *flashMgr = m_exynosCameraActivityControl->getFlashMgr(); |
| m_skipCount = 0; |
| |
| if (m_getRecordingEnabled() == false) { |
| return; |
| } |
| m_setRecordingEnabled(false); |
| |
| #ifdef SAMSUNG_HLV |
| if (m_HLV != NULL) |
| { |
| UNI_PLUGIN_CAPTURE_STATUS value = UNI_PLUGIN_CAPTURE_STATUS_VID_REC_STOP; |
| ALOGD("HLV: set UNI_PLUGIN_CAPTURE_STATUS_VID_REC_STOP"); |
| |
| uni_plugin_set(m_HLV, |
| HIGHLIGHT_VIDEO_PLUGIN_NAME, |
| UNI_PLUGIN_INDEX_CAPTURE_STATUS, |
| &value); |
| |
| /* De-Init should be called before m_stopRecordingInternal to avoid race-condition in libHighLightVideo */ |
| ALOGD("HLV : uni_plugin_deinit !!!"); |
| ret = uni_plugin_deinit(m_HLV); |
| if (ret) { |
| ALOGE("HLV : uni_plugin_deinit failed !! Possible Memory Leak !!!"); |
| } |
| |
| ret = uni_plugin_unload(&m_HLV); |
| if (ret) |
| ALOGE("HLV : uni_plug_unload failed !! Possible Memory Leak !!!"); |
| |
| m_HLV = NULL; |
| ALOGD("HLV : process_step : %d", m_HLVprocessStep); |
| } |
| #endif |
| |
| /* Do stop recording process */ |
| ret = m_stopRecordingInternal(); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):m_stopRecordingInternal fail", __FUNCTION__, __LINE__); |
| |
| #ifdef USE_FD_AE |
| if (m_exynosCameraParameters != NULL) { |
| m_startFaceDetection(m_exynosCameraParameters->getFaceDetectionMode(false)); |
| } |
| #endif |
| |
| autoFocusMgr->setRecordingHint(false); |
| flashMgr->setRecordingHint(false); |
| flashMgr->setNeedFlashOffDelay(false); |
| } |
| |
| bool ExynosCamera::recordingEnabled() |
| { |
| bool ret = m_getRecordingEnabled(); |
| CLOGI("INFO(%s[%d]):m_recordingEnabled=%d", |
| __FUNCTION__, __LINE__, (int)ret); |
| |
| return ret; |
| } |
| |
| void ExynosCamera::releaseRecordingFrame(const void *opaque) |
| { |
| if (m_exynosCameraParameters != NULL) { |
| if (m_exynosCameraParameters->getVisionMode() == true) { |
| CLOGW("WRN(%s[%d]): Vision mode does not support", __FUNCTION__, __LINE__); |
| android_printAssert(NULL, LOG_TAG, "Cannot support this operation"); |
| |
| return; |
| } |
| } |
| |
| if (m_getRecordingEnabled() == false) { |
| CLOGW("WARN(%s[%d]):m_recordingEnabled equals false", __FUNCTION__, __LINE__); |
| /* m_stopRecordingInternal() will wait for recording frame release */ |
| /* return; */ |
| } |
| |
| if (m_recordingCallbackHeap == NULL) { |
| CLOGW("WARN(%s[%d]):recordingCallbackHeap equals NULL", __FUNCTION__, __LINE__); |
| return; |
| } |
| |
| struct VideoNativeHandleMetadata *releaseMetadata = (struct VideoNativeHandleMetadata *) opaque; |
| native_handle_t *releaseHandle = NULL; |
| int releaseBufferIndex = -1; |
| |
| if (releaseMetadata->eType != kMetadataBufferTypeNativeHandleSource) { |
| CLOGW("WARN(%s[%d]):Inavlid VideoNativeHandleMetadata Type %d", |
| __FUNCTION__, __LINE__, |
| releaseMetadata->eType); |
| return; |
| } |
| |
| /* |
| * Support only NV21M, |
| * data[0]: Y |
| * data[1]: CbCr |
| * data[2]: bufferIndex |
| */ |
| releaseHandle = releaseMetadata->pHandle; |
| releaseBufferIndex = releaseHandle->data[2]; |
| if (releaseBufferIndex >= m_recordingBufferCount) { |
| CLOGW("WARN(%s[%d]):Invalid VideoBufferIndex %d", |
| __FUNCTION__, __LINE__, |
| releaseBufferIndex); |
| |
| goto CLEAN; |
| } else if (m_recordingBufAvailable[releaseBufferIndex] == true) { |
| CLOGW("WARN(%s[%d]):Already released VideoBufferIndex %d", |
| __FUNCTION__, __LINE__, |
| releaseBufferIndex); |
| |
| goto CLEAN; |
| } |
| |
| if (m_doCscRecording == true) { |
| m_releaseRecordingBuffer(releaseBufferIndex); |
| } |
| |
| m_recordingTimeStamp[releaseBufferIndex] = 0L; |
| m_recordingBufAvailable[releaseBufferIndex] = true; |
| |
| m_isFirstStart = false; |
| if (m_exynosCameraParameters != NULL) { |
| m_exynosCameraParameters->setIsFirstStartFlag(m_isFirstStart); |
| } |
| |
| CLEAN: |
| if (releaseHandle != NULL) { |
| native_handle_close(releaseHandle); |
| native_handle_delete(releaseHandle); |
| } |
| |
| return; |
| } |
| |
| status_t ExynosCamera::autoFocus() |
| { |
| CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__); |
| |
| if (m_exynosCameraParameters != NULL) { |
| if (m_exynosCameraParameters->getVisionMode() == true) { |
| CLOGW("WRN(%s[%d]): Vision mode does not support", __FUNCTION__, __LINE__); |
| android_printAssert(NULL, LOG_TAG, "Cannot support this operation"); |
| |
| return INVALID_OPERATION; |
| } |
| } |
| |
| if (m_previewEnabled == false) { |
| CLOGE("ERR(%s[%d]): preview is not enabled", __FUNCTION__, __LINE__); |
| return INVALID_OPERATION; |
| } |
| |
| if (m_autoFocusRunning == false) { |
| m_autoFocusType = AUTO_FOCUS_SERVICE; |
| m_autoFocusThread->requestExitAndWait(); |
| m_autoFocusThread->run(PRIORITY_DEFAULT); |
| } else { |
| CLOGW("WRN(%s[%d]): auto focus is inprogressing", __FUNCTION__, __LINE__); |
| } |
| |
| #if 0 // not used. |
| if (m_exynosCameraParameters != NULL) { |
| if (m_exynosCameraParameters->getFocusMode() == FOCUS_MODE_AUTO) { |
| CLOGI("INFO(%s[%d]) ae awb lock", __FUNCTION__, __LINE__); |
| m_exynosCameraParameters->m_setAutoExposureLock(true); |
| m_exynosCameraParameters->m_setAutoWhiteBalanceLock(true); |
| } |
| } |
| #endif |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::cancelAutoFocus() |
| { |
| CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__); |
| |
| if (m_exynosCameraParameters != NULL) { |
| if (m_exynosCameraParameters->getVisionMode() == true) { |
| CLOGW("WRN(%s[%d]): Vision mode does not support", __FUNCTION__, __LINE__); |
| android_printAssert(NULL, LOG_TAG, "Cannot support this operation"); |
| |
| return INVALID_OPERATION; |
| } |
| } |
| |
| m_autoFocusRunning = false; |
| |
| #ifdef SAMSUNG_DOF |
| if(m_lensmoveCount) { |
| CLOGW("[DOF][%s][%d] Out-focus shot parameter is not reset. Reset here forcely!!: %d", |
| __FUNCTION__, __LINE__, m_lensmoveCount); |
| ExynosCameraActivityAutofocus *autoFocusMgr = m_exynosCameraActivityControl->getAutoFocusMgr(); |
| autoFocusMgr->setStartLensMove(false); |
| m_lensmoveCount = 0; |
| m_exynosCameraParameters->setMoveLensCount(m_lensmoveCount); |
| m_exynosCameraParameters->setMoveLensTotal(m_lensmoveCount); |
| } |
| #endif |
| |
| #if 0 // not used. |
| if (m_exynosCameraParameters != NULL) { |
| if (m_exynosCameraParameters->getFocusMode() == FOCUS_MODE_AUTO) { |
| CLOGI("INFO(%s[%d]) ae awb unlock", __FUNCTION__, __LINE__); |
| m_exynosCameraParameters->m_setAutoExposureLock(false); |
| m_exynosCameraParameters->m_setAutoWhiteBalanceLock(false); |
| } |
| } |
| #endif |
| |
| if (m_exynosCameraActivityControl->cancelAutoFocus() == false) { |
| CLOGE("ERR(%s):Fail on m_secCamera->cancelAutoFocus()", __FUNCTION__); |
| return UNKNOWN_ERROR; |
| } |
| |
| /* if autofocusThread is running, we should be wait to receive the AF reseult. */ |
| m_autoFocusLock.lock(); |
| m_autoFocusLock.unlock(); |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::takePicture() |
| { |
| int ret = 0; |
| int takePictureCount = m_takePictureCounter.getCount(); |
| int seriesShotCount = 0; |
| int currentSeriesShotMode = 0; |
| ExynosCameraFrame *newFrame = NULL; |
| int32_t reprocessingBayerMode = 0; |
| int retryCount = 0; |
| |
| if (m_previewEnabled == false) { |
| CLOGE("DEBUG(%s):preview is stopped, return error", __FUNCTION__); |
| return INVALID_OPERATION; |
| } |
| |
| if (m_exynosCameraParameters == NULL) { |
| CLOGE("ERR(%s):m_exynosCameraParameters is NULL", __FUNCTION__); |
| return INVALID_OPERATION; |
| } |
| |
| while (m_longExposurePreview) { |
| m_exynosCameraParameters->setPreviewExposureTime(); |
| |
| uint64_t delay = 0; |
| if (m_exynosCameraParameters->getCaptureExposureTime() <= 33333) { |
| delay = 30000; |
| } else if (m_exynosCameraParameters->getCaptureExposureTime() > CAMERA_EXPOSURE_TIME_MAX) { |
| delay = CAMERA_EXPOSURE_TIME_MAX; |
| } else { |
| delay = m_exynosCameraParameters->getCaptureExposureTime(); |
| } |
| |
| usleep(delay); |
| |
| if (++retryCount > 7) { |
| CLOGE("DEBUG(%s):HAL can not set preview exposure time. Returns error.", __FUNCTION__); |
| return INVALID_OPERATION; |
| } |
| } |
| |
| retryCount = 0; |
| #ifdef SAMSUNG_DNG |
| m_dngFrameNumberForManualExposure = 0; |
| #endif |
| |
| /* wait autoFocus is over for turning on preFlash */ |
| m_autoFocusThread->join(); |
| |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| /* For Sync with jpegCallbackThread */ |
| m_captureLock.lock(); |
| #endif |
| |
| seriesShotCount = m_exynosCameraParameters->getSeriesShotCount(); |
| currentSeriesShotMode = m_exynosCameraParameters->getSeriesShotMode(); |
| reprocessingBayerMode = m_exynosCameraParameters->getReprocessingBayerMode(); |
| if (m_exynosCameraParameters->getVisionMode() == true) { |
| CLOGW("WRN(%s[%d]): Vision mode does not support", __FUNCTION__, __LINE__); |
| android_printAssert(NULL, LOG_TAG, "Cannot support this operation"); |
| |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| m_captureLock.unlock(); |
| #endif |
| return INVALID_OPERATION; |
| } |
| |
| if (m_exynosCameraParameters->getShotMode() == SHOT_MODE_RICH_TONE) { |
| m_hdrEnabled = true; |
| } else { |
| m_hdrEnabled = false; |
| } |
| |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| TakepictureDurationTimer.stop(); |
| if (m_exynosCameraParameters->getSamsungCamera() && getCameraId() == CAMERA_ID_BACK |
| && !m_exynosCameraParameters->getRecordingHint() |
| && !m_getRecordingEnabled() |
| && !m_exynosCameraParameters->getDualMode() |
| && !m_exynosCameraParameters->getEffectHint() |
| #ifdef SAMSUNG_DNG |
| && !m_exynosCameraParameters->getDNGCaptureModeOn() |
| #endif |
| && (currentSeriesShotMode == SERIES_SHOT_MODE_NONE || currentSeriesShotMode == SERIES_SHOT_MODE_ONE_SECOND_BURST)) { |
| uint64_t delay; |
| uint64_t sum; |
| delay = TakepictureDurationTimer.durationUsecs(); |
| ExynosCameraActivityFlash *m_flashMgr = m_exynosCameraActivityControl->getFlashMgr(); |
| ExynosCameraActivitySpecialCapture *m_sCaptureMgr = m_exynosCameraActivityControl->getSpecialCaptureMgr(); |
| |
| /* set smallest delay */ |
| if (ONE_SECOND_BURST_CAPTURE_TAKEPICTURE_COUNT == 1 |
| && m_one_second_burst_first_after_open == true) |
| delay = 1; |
| |
| /* Check other shot(OIS, HDR without companion, FLASH) launching */ |
| #ifdef OIS_CAPTURE |
| if(getCameraId() == CAMERA_ID_BACK && currentSeriesShotMode != SERIES_SHOT_MODE_BURST) { |
| m_sCaptureMgr->resetOISCaptureFcount(); |
| m_exynosCameraParameters->checkOISCaptureMode(); |
| #ifdef SAMSUNG_LLS_DEBLUR |
| m_exynosCameraParameters->checkLDCaptureMode(); |
| #endif |
| } |
| #endif |
| /* SR, Burst, LLS is already disable on sendCommand() */ |
| if (m_hdrEnabled |
| || (m_exynosCameraParameters->getShotMode() == SHOT_MODE_OUTFOCUS) |
| || (m_exynosCameraParameters->getFlashMode() == FLASH_MODE_ON) |
| || (getCameraId() == CAMERA_ID_BACK && m_exynosCameraParameters->getOISCaptureModeOn() == true) |
| #ifdef SAMSUNG_LLS_DEBLUR |
| || (m_exynosCameraParameters->getLDCaptureMode() > 0) |
| #endif |
| || (m_flashMgr->getNeedCaptureFlash() == true && currentSeriesShotMode == SERIES_SHOT_MODE_NONE) |
| || (m_exynosCameraParameters->getCaptureExposureTime() != 0) |
| || m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_RAW_IMAGE)) { // HAL test (Ext_SecCameraActivityTest_testTakePicture_P01) |
| /* Check other shot only. reset Capturemode */ |
| m_exynosCameraParameters->setOISCaptureModeOn(false); |
| #ifdef SAMSUNG_LLS_DEBLUR |
| m_exynosCameraParameters->setLDCaptureMode(MULTI_SHOT_MODE_NONE); |
| m_exynosCameraParameters->setLDCaptureCount(0); |
| m_exynosCameraParameters->setLDCaptureLLSValue(LLS_LEVEL_ZSL); |
| #endif |
| /* For jpegCallbackThreadFunc() exit */ |
| m_captureLock.unlock(); |
| m_clearOneSecondBurst(false); |
| m_captureLock.lock(); |
| /* Reset value */ |
| currentSeriesShotMode = m_exynosCameraParameters->getSeriesShotMode(); |
| seriesShotCount = m_exynosCameraParameters->getSeriesShotCount(); |
| takePictureCount = m_takePictureCounter.getCount(); |
| /* clear delay */ |
| delay = 0; |
| } |
| |
| if (currentSeriesShotMode == SERIES_SHOT_MODE_NONE) { |
| if (delay <= ONE_SECOND_BURST_CAPTURE_CHECK_TIME * ONE_MSECOND) { |
| sum = 0; |
| for (int i = 0; i < ONE_SECOND_BURST_CAPTURE_CHECK_COUNT; i++) { |
| if (TakepictureDurationTime[i] != 0) |
| sum += TakepictureDurationTime[i]; |
| |
| if (TakepictureDurationTime[i] == 0) { |
| TakepictureDurationTime[i] = delay; |
| sum += TakepictureDurationTime[i]; |
| break; |
| } |
| } |
| if (sum >= ONE_SECOND_BURST_CAPTURE_CHECK_TIME * ONE_MSECOND) { |
| /* Remove unnecessary time */ |
| for (int i = 0; i < ONE_SECOND_BURST_CAPTURE_CHECK_COUNT - 1; i++) { |
| TakepictureDurationTime[i] = TakepictureDurationTime[i + 1]; |
| } |
| TakepictureDurationTime[ONE_SECOND_BURST_CAPTURE_CHECK_COUNT - 1] = 0; |
| } else { |
| if (TakepictureDurationTime[ONE_SECOND_BURST_CAPTURE_CHECK_COUNT - 1] != 0) { |
| /* do one second burst */ |
| CLOGD("DEBUG(%s[%d]): One second burst start - TimeCheck", __FUNCTION__, __LINE__); |
| m_one_second_burst_first_after_open = true; |
| for (int i = 0; i < ONE_SECOND_BURST_CAPTURE_CHECK_COUNT; i++) { |
| TakepictureDurationTime[i] = 0; |
| } |
| /* Set one second burst parameters */ |
| m_one_second_burst_capture = true; |
| |
| if (m_burstInitFirst) { |
| m_burstRealloc = true; |
| m_burstInitFirst = false; |
| } |
| m_exynosCameraParameters->setSeriesShotMode(SERIES_SHOT_MODE_ONE_SECOND_BURST); |
| /* Set value */ |
| currentSeriesShotMode = m_exynosCameraParameters->getSeriesShotMode(); |
| seriesShotCount = m_exynosCameraParameters->getSeriesShotCount(); |
| m_takePictureCounter.setCount(0); |
| takePictureCount = m_takePictureCounter.getCount(); |
| |
| m_burstCaptureCallbackCount = 0; |
| m_exynosCameraParameters->setSeriesShotSaveLocation(BURST_SAVE_CALLBACK); |
| m_jpegCallbackCounter.setCount(seriesShotCount); |
| #ifdef USE_DVFS_LOCK |
| m_exynosCameraParameters->setDvfsLock(true); |
| #endif |
| /* Clear saved CallbackHeap */ |
| if (m_one_second_jpegCallbackHeap != NULL) { |
| m_one_second_jpegCallbackHeap->release(m_one_second_jpegCallbackHeap); |
| m_one_second_jpegCallbackHeap = NULL; |
| } |
| if (m_one_second_postviewCallbackHeap != NULL) { |
| m_one_second_postviewCallbackHeap->release(m_one_second_postviewCallbackHeap); |
| m_one_second_postviewCallbackHeap = NULL; |
| } |
| } |
| } |
| } else { |
| /* Init TakepictureDurationTime. Delay is too big */ |
| for (int i = 0; i < ONE_SECOND_BURST_CAPTURE_CHECK_COUNT; i++) |
| TakepictureDurationTime[i] = 0; |
| } |
| } else if (currentSeriesShotMode == SERIES_SHOT_MODE_ONE_SECOND_BURST) { |
| /* More one second burst */ |
| /* We add 1 to seriesShotCount because we can't know thread state. |
| We will check m_jpegCallbackCounter is smaller than 1 */ |
| CLOGD("DEBUG(%s[%d]): Continue One second burst - TimeCheck", __FUNCTION__, __LINE__); |
| m_reprocessingCounter.setCount(seriesShotCount + 1); |
| m_jpegCounter.setCount(seriesShotCount + 1); |
| m_pictureCounter.setCount(seriesShotCount + 1); |
| m_jpegCallbackCounter.setCount(seriesShotCount); |
| /* Make difference m_takePictureCounter value with seriesShotCount */ |
| m_takePictureCounter.setCount(seriesShotCount - 1); |
| takePictureCount = m_takePictureCounter.getCount(); |
| m_burstCaptureCallbackCount = 0; |
| m_one_second_burst_capture = true; |
| |
| if (m_prePictureThread->isRunning() == false) { |
| if (m_prePictureThread->run(PRIORITY_DEFAULT) != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):couldn't run pre-picture thread", __FUNCTION__, __LINE__); |
| m_captureLock.unlock(); |
| return INVALID_OPERATION; |
| } |
| } |
| if (m_pictureThread->isRunning() == false) { |
| if (m_pictureThread->run() != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):couldn't run picture thread, ret(%d)", __FUNCTION__, __LINE__, ret); |
| m_captureLock.unlock(); |
| return INVALID_OPERATION; |
| } |
| } |
| } |
| } |
| TakepictureDurationTimer.start(); |
| #endif |
| |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| m_captureLock.unlock(); |
| #endif |
| |
| m_exynosCameraParameters->setMarkingOfExifFlash(0); |
| |
| #ifdef SAMSUNG_LBP |
| if (getCameraId() == CAMERA_ID_FRONT) |
| m_exynosCameraParameters->resetNormalBestFrameCount(); |
| #endif |
| |
| /* HACK Reset Preview Flag*/ |
| while ((m_resetPreview == true) && (retryCount < 10)) { |
| usleep(200000); |
| retryCount ++; |
| CLOGI("INFO(%s[%d]) retryCount(%d) m_resetPreview(%d)", __FUNCTION__, __LINE__, retryCount, m_resetPreview); |
| } |
| |
| if (takePictureCount < 0) { |
| CLOGE("ERR(%s[%d]): takePicture is called too much. takePictureCount(%d) / seriesShotCount(%d) . so, fail", |
| __FUNCTION__, __LINE__, takePictureCount, seriesShotCount); |
| return INVALID_OPERATION; |
| } else if (takePictureCount == 0) { |
| if (seriesShotCount == 0) { |
| m_captureLock.lock(); |
| if (m_pictureEnabled == true) { |
| CLOGE("ERR(%s[%d]): take picture is inprogressing", __FUNCTION__, __LINE__); |
| /* return NO_ERROR; */ |
| m_captureLock.unlock(); |
| return INVALID_OPERATION; |
| } |
| m_captureLock.unlock(); |
| |
| /* general shot */ |
| seriesShotCount = 1; |
| } |
| m_takePictureCounter.setCount(seriesShotCount); |
| } |
| |
| CLOGI("INFO(%s[%d]): takePicture start m_takePictureCounter(%d), currentSeriesShotMode(%d) seriesShotCount(%d)", |
| __FUNCTION__, __LINE__, m_takePictureCounter.getCount(), currentSeriesShotMode, seriesShotCount); |
| |
| m_printExynosCameraInfo(__FUNCTION__); |
| |
| /* TODO: Dynamic bayer capture, currently support only single shot */ |
| if (reprocessingBayerMode == REPROCESSING_BAYER_MODE_PURE_DYNAMIC) { |
| int pipeId = m_getBayerPipeId(); |
| |
| if (m_bayerBufferMgr->getNumOfAvailableBuffer() > 0) { |
| m_previewFrameFactory->setRequestFLITE(true); |
| ret = generateFrame(-1, &newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):generateFrame fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| m_previewFrameFactory->setRequestFLITE(false); |
| |
| ret = m_setupEntity(pipeId, newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, pipeId); |
| m_previewFrameFactory->pushFrameToPipe(&newFrame, pipeId); |
| } |
| |
| m_previewFrameFactory->startThread(pipeId); |
| } else if (reprocessingBayerMode == REPROCESSING_BAYER_MODE_DIRTY_DYNAMIC) { |
| /* Comment out, because it included 3AA, it always running */ |
| /* |
| int pipeId = m_getBayerPipeId(); |
| |
| if (m_bayerBufferMgr->getNumOfAvailableBuffer() > 0) { |
| m_previewFrameFactory->setRequest3AC(true); |
| ret = generateFrame(-1, &newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):generateFrame fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| m_previewFrameFactory->setRequest3AC(false); |
| |
| ret = m_setupEntity(pipeId, newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, pipeId); |
| m_previewFrameFactory->pushFrameToPipe(&newFrame, pipeId); |
| } |
| |
| m_previewFrameFactory->startThread(pipeId); |
| */ |
| if (m_bayerBufferMgr->getNumOfAvailableBuffer() > 0) |
| m_previewFrameFactory->setRequest3AC(true); |
| } |
| |
| if (m_takePictureCounter.getCount() == seriesShotCount) { |
| ExynosCameraActivitySpecialCapture *m_sCaptureMgr = m_exynosCameraActivityControl->getSpecialCaptureMgr(); |
| ExynosCameraActivityFlash *m_flashMgr = m_exynosCameraActivityControl->getFlashMgr(); |
| |
| m_stopBurstShot = false; |
| #ifdef BURST_CAPTURE |
| m_burstShutterLocation = BURST_SHUTTER_PREPICTURE; |
| #endif |
| |
| if (m_exynosCameraParameters->isReprocessing() == true) |
| m_captureSelector->setIsFirstFrame(true); |
| else |
| m_sccCaptureSelector->setIsFirstFrame(true); |
| |
| #if 0 |
| if (m_exynosCameraParameters->isReprocessing() == false || m_exynosCameraParameters->getSeriesShotCount() > 0 || |
| m_hdrEnabled == true) { |
| m_pictureFrameFactory = m_previewFrameFactory; |
| if (m_exynosCameraParameters->getUseDynamicScc() == true) { |
| if (isOwnScc(getCameraId()) == true) |
| m_previewFrameFactory->setRequestSCC(true); |
| else |
| m_previewFrameFactory->setRequestISPC(true); |
| |
| /* boosting dynamic SCC */ |
| if (m_hdrEnabled == false && |
| currentSeriesShotMode == SERIES_SHOT_MODE_NONE) { |
| ret = m_boostDynamicCapture(); |
| if (ret < 0) |
| CLOGW("WRN(%s[%d]): fail to boosting dynamic capture", __FUNCTION__, __LINE__); |
| } |
| |
| } |
| } else { |
| m_pictureFrameFactory = m_reprocessingFrameFactory; |
| } |
| #endif |
| |
| if (m_exynosCameraParameters->getScalableSensorMode()) { |
| m_exynosCameraParameters->setScalableSensorMode(false); |
| stopPreview(); |
| setPreviewWindow(m_previewWindow); |
| startPreview(); |
| m_exynosCameraParameters->setScalableSensorMode(true); |
| } |
| |
| CLOGI("INFO(%s[%d]): takePicture enabled, takePictureCount(%d)", |
| __FUNCTION__, __LINE__, m_takePictureCounter.getCount()); |
| m_pictureEnabled = true; |
| m_takePictureCounter.decCount(); |
| m_isNeedAllocPictureBuffer = true; |
| |
| m_startPictureBufferThread->join(); |
| |
| if (m_exynosCameraParameters->isReprocessing() == true) { |
| m_startPictureInternalThread->join(); |
| |
| #ifdef BURST_CAPTURE |
| #ifdef CAMERA_GED_FEATURE |
| if (seriesShotCount > 1) |
| #else |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| if ((m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_BURST |
| || m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_ONE_SECOND_BURST) |
| && m_burstRealloc == true) |
| #else |
| if (m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_BURST && m_burstRealloc == true) |
| #endif |
| #endif |
| { |
| int allocCount = 0; |
| int addCount = 0; |
| CLOGD("DEBUG(%s[%d]): realloc buffer for burst shot", __FUNCTION__, __LINE__); |
| m_burstRealloc = false; |
| |
| allocCount = m_sccReprocessingBufferMgr->getAllocatedBufferCount(); |
| addCount = (allocCount <= NUM_BURST_GSC_JPEG_INIT_BUFFER)?(NUM_BURST_GSC_JPEG_INIT_BUFFER-allocCount):0; |
| if( addCount > 0 ){ |
| m_sccReprocessingBufferMgr->increase(addCount); |
| } |
| |
| allocCount = m_jpegBufferMgr->getAllocatedBufferCount(); |
| addCount = (allocCount <= NUM_BURST_GSC_JPEG_INIT_BUFFER)?(NUM_BURST_GSC_JPEG_INIT_BUFFER-allocCount):0; |
| if( addCount > 0 ){ |
| m_jpegBufferMgr->increase(addCount); |
| } |
| m_isNeedAllocPictureBuffer = true; |
| } |
| #endif |
| } |
| |
| CLOGD("DEBUG(%s[%d]): currentSeriesShotMode(%d), m_flashMgr->getNeedCaptureFlash(%d)", |
| __FUNCTION__, __LINE__, currentSeriesShotMode, m_flashMgr->getNeedCaptureFlash()); |
| |
| #ifdef RAWDUMP_CAPTURE |
| if(m_use_companion == true) { |
| CLOGD("DEBUG(%s[%d]): start set Raw Capture mode", __FUNCTION__, __LINE__); |
| m_sCaptureMgr->resetRawCaptureFcount(); |
| m_sCaptureMgr->setCaptureMode(ExynosCameraActivitySpecialCapture::SCAPTURE_MODE_RAW); |
| |
| m_exynosCameraParameters->setRawCaptureModeOn(true); |
| |
| enum aa_capture_intent captureIntent = AA_CAPTRUE_INTENT_STILL_CAPTURE_COMP_BYPASS; |
| |
| ret = m_previewFrameFactory->setControl(V4L2_CID_IS_INTENT, captureIntent, PIPE_3AA); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):setControl(STILL_CAPTURE_RAW) fail. ret(%d) intent(%d)", |
| __FUNCTION__, __LINE__, ret, captureIntent); |
| m_sCaptureMgr->setCaptureStep(ExynosCameraActivitySpecialCapture::SCAPTURE_STEP_START); |
| } |
| #else |
| #ifdef OIS_CAPTURE |
| if (getCameraId() == CAMERA_ID_BACK |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| && currentSeriesShotMode != SERIES_SHOT_MODE_ONE_SECOND_BURST |
| #endif |
| && !m_getRecordingEnabled() |
| ) { |
| m_sCaptureMgr->resetOISCaptureFcount(); |
| m_exynosCameraParameters->checkOISCaptureMode(); |
| #if defined(SAMSUNG_DEBLUR) || defined(SAMSUNG_LLS_DEBLUR) |
| if (currentSeriesShotMode == SERIES_SHOT_MODE_NONE) { |
| m_exynosCameraParameters->checkLDCaptureMode(); |
| CLOGD("LDC(%s[%d]): currentSeriesShotMode(%d), getLDCaptureMode(%d)", |
| __FUNCTION__, __LINE__, currentSeriesShotMode, m_exynosCameraParameters->getLDCaptureMode()); |
| } |
| #ifdef SAMSUNG_DEBLUR |
| if (m_exynosCameraParameters->getLDCaptureMode() == MULTI_SHOT_MODE_DEBLUR) { |
| m_captureSelector->setFrameHoldCount(MAX_DEBLUR_CAPTURE_COUNT); |
| } |
| #endif |
| #endif |
| } |
| #endif |
| |
| #if defined(SAMSUNG_DEBLUR) || defined(SAMSUNG_LLS_DEBLUR) |
| if (getCameraId() == CAMERA_ID_FRONT && currentSeriesShotMode == SERIES_SHOT_MODE_NONE |
| && isLDCapture(getCameraId()) && !m_getRecordingEnabled()) { |
| m_exynosCameraParameters->checkLDCaptureMode(); |
| CLOGD("LDC(%s[%d]): currentSeriesShotMode(%d), getLDCaptureMode(%d)", |
| __FUNCTION__, __LINE__, currentSeriesShotMode, m_exynosCameraParameters->getLDCaptureMode()); |
| } |
| #endif |
| |
| if (m_exynosCameraParameters->getCaptureExposureTime() != 0) { |
| m_longExposureRemainCount = m_exynosCameraParameters->getLongExposureShotCount(); |
| } |
| |
| #ifdef SAMSUNG_DNG |
| if (getCameraId() == CAMERA_ID_BACK |
| && (currentSeriesShotMode == SERIES_SHOT_MODE_NONE || currentSeriesShotMode == SERIES_SHOT_MODE_LLS) |
| && m_exynosCameraParameters->getDNGCaptureModeOn() |
| && !m_getRecordingEnabled()) { |
| int buffercount = 1; |
| m_longExposureEnds = false; |
| m_dngLongExposureRemainCount = 0; |
| |
| m_captureSelector->resetDNGFrameCount(); |
| m_exynosCameraParameters->setCheckMultiFrame(false); |
| m_exynosCameraParameters->setUseDNGCapture(true); |
| m_exynosCameraParameters->setDngSaveLocation(BURST_SAVE_PHONE); |
| |
| if (m_exynosCameraParameters->getOISCaptureModeOn() || |
| m_flashMgr->getNeedCaptureFlash() == true || |
| m_exynosCameraParameters->getCaptureExposureTime() > CAMERA_PREVIEW_EXPOSURE_TIME_LIMIT) { |
| m_exynosCameraParameters->setCheckMultiFrame(true); |
| m_searchDNGFrame = true; |
| buffercount = 3; |
| m_flashMgr->resetShotFcount(); |
| if (m_exynosCameraParameters->getLongExposureShotCount() > 0) { |
| m_dngLongExposureRemainCount = m_exynosCameraParameters->getLongExposureShotCount(); |
| } |
| } |
| CLOGD("[DNG](%s[%d]): start set DNG Capture mode m_use_DNGCapture(%d) m_flagMultiFrame(%d)", |
| __FUNCTION__, __LINE__, m_exynosCameraParameters->getUseDNGCapture(), |
| m_exynosCameraParameters->getCheckMultiFrame()); |
| |
| int pipeId = PIPE_FLITE; |
| ExynosCameraBuffer newBuffer; |
| int dstbufferIndex = 0; |
| |
| if (m_fliteBufferMgr->getNumOfAvailableBuffer() > 0) { |
| m_previewFrameFactory->setRequestFLITE(true); |
| |
| for (int i = 0; i < buffercount; i++) { |
| ret = generateFrame(-1, &newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):generateFrame fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| newBuffer.index = -2; |
| dstbufferIndex = -1; |
| |
| m_fliteFrameCount++; |
| m_fliteBufferMgr->getBuffer(&dstbufferIndex, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL, &newBuffer); |
| |
| CLOGD("[DNG](%s[%d]):create DNG capture frame(%d) index(%d)", |
| __FUNCTION__, __LINE__, newFrame->getFrameCount(), newBuffer.index); |
| |
| ret = m_setupEntity(pipeId, newFrame, NULL, &newBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, pipeId); |
| m_previewFrameFactory->pushFrameToPipe(&newFrame, pipeId); |
| } |
| |
| m_fliteFrameCount = newFrame->getFrameCount() + 1; |
| |
| if (!m_exynosCameraParameters->getCheckMultiFrame()) { |
| m_previewFrameFactory->setRequestFLITE(false); |
| } |
| } |
| |
| m_previewFrameFactory->startThread(pipeId); |
| } |
| #endif |
| |
| #ifdef SAMSUNG_LBP |
| if (currentSeriesShotMode == SERIES_SHOT_MODE_NONE) { |
| uint32_t refBestPicCount = 0; |
| if(getCameraId() == CAMERA_ID_FRONT) { |
| if (m_exynosCameraParameters->getSCPFrameCount() >= m_exynosCameraParameters->getBayerFrameCount()) { |
| refBestPicCount = m_exynosCameraParameters->getSCPFrameCount() + LBP_CAPTURE_DELAY; |
| } else { |
| refBestPicCount = m_exynosCameraParameters->getBayerFrameCount() + LBP_CAPTURE_DELAY; |
| } |
| } |
| |
| if(getCameraId() == CAMERA_ID_FRONT) { |
| if(m_isLBPlux == true && m_getRecordingEnabled() == false) { |
| m_exynosCameraParameters->setNormalBestFrameCount(refBestPicCount); |
| m_captureSelector->setFrameIndex(refBestPicCount); |
| |
| ret = m_captureSelector->setFrameHoldCount(m_exynosCameraParameters->getHoldFrameCount()); |
| m_isLBPon = true; |
| } else { |
| m_isLBPon = false; |
| } |
| } else { |
| #if !defined(SAMSUNG_DEBLUR) && !defined(SAMSUNG_LLS_DEBLUR) |
| if(m_isLBPlux == true && m_exynosCameraParameters->getOISCaptureModeOn() == true |
| #ifdef SAMSUNG_DNG |
| && m_exynosCameraParameters->getDNGCaptureModeOn() == false |
| #endif |
| && m_getRecordingEnabled() == false) { |
| ret = m_captureSelector->setFrameHoldCount(m_exynosCameraParameters->getHoldFrameCount()); |
| m_isLBPon = true; |
| } |
| else |
| #endif |
| { |
| m_isLBPon = false; |
| } |
| } |
| } |
| #endif |
| #ifdef SAMSUNG_JQ |
| if (currentSeriesShotMode == SERIES_SHOT_MODE_NONE) { |
| CLOGD("[JQ](%s[%d]): ON!!", __FUNCTION__, __LINE__); |
| m_isJpegQtableOn = true; |
| m_exynosCameraParameters->setJpegQtableOn(true); |
| } |
| else { |
| CLOGD("[JQ](%s[%d]): OFF!!", __FUNCTION__, __LINE__); |
| m_isJpegQtableOn = false; |
| m_exynosCameraParameters->setJpegQtableOn(false); |
| } |
| #endif |
| if (m_hdrEnabled == true) { |
| seriesShotCount = HDR_REPROCESSING_COUNT; |
| m_sCaptureMgr->setCaptureStep(ExynosCameraActivitySpecialCapture::SCAPTURE_STEP_START); |
| m_sCaptureMgr->resetHdrStartFcount(); |
| m_exynosCameraParameters->setFrameSkipCount(13); |
| } else if ((m_flashMgr->getNeedCaptureFlash() == true && currentSeriesShotMode == SERIES_SHOT_MODE_NONE) |
| #ifdef FLASHED_LLS_CAPTURE |
| || (m_flashMgr->getNeedCaptureFlash() == true && currentSeriesShotMode == SERIES_SHOT_MODE_LLS |
| #ifdef SR_CAPTURE |
| && m_exynosCameraParameters->getSROn() == false |
| #endif |
| ) |
| #endif |
| ) { |
| if (m_exynosCameraParameters->getCaptureExposureTime() != 0) { |
| m_stopLongExposure = false; |
| m_flashMgr->setManualExposureTime(m_exynosCameraParameters->getLongExposureTime() * 1000); |
| } |
| |
| m_exynosCameraParameters->setMarkingOfExifFlash(1); |
| |
| #ifdef FLASHED_LLS_CAPTURE |
| if (currentSeriesShotMode == SERIES_SHOT_MODE_LLS) { |
| m_captureSelector->setFlashedLLSCaptureStatus(true); |
| #ifdef LLS_REPROCESSING |
| m_sCaptureMgr->setIsFlashLLSCapture(true); |
| #endif |
| } |
| #endif |
| if (m_flashMgr->checkPreFlash() == false && m_isTryStopFlash == false) { |
| m_flashMgr->setCaptureStatus(true); |
| CLOGD("DEBUG(%s[%d]): checkPreFlash(false), Start auto focus internally", __FUNCTION__, __LINE__); |
| m_autoFocusType = AUTO_FOCUS_HAL; |
| m_flashMgr->setFlashTrigerPath(ExynosCameraActivityFlash::FLASH_TRIGGER_SHORT_BUTTON); |
| m_flashMgr->setFlashWaitCancel(false); |
| |
| /* execute autoFocus for preFlash */ |
| m_autoFocusThread->requestExitAndWait(); |
| m_autoFocusThread->run(PRIORITY_DEFAULT); |
| } |
| } |
| #ifdef OIS_CAPTURE |
| else if (m_exynosCameraParameters->getOISCaptureModeOn() == true |
| && getCameraId() == CAMERA_ID_BACK) { |
| CLOGD("DEBUG(%s[%d]): start set zsl-like mode", __FUNCTION__, __LINE__); |
| |
| int captureIntent; |
| #ifdef SAMSUNG_LBP |
| m_sCaptureMgr->setBestMultiCaptureMode(false); |
| #endif |
| |
| if (m_exynosCameraParameters->getSeriesShotCount() > 0 |
| #ifdef LLS_REPROCESSING |
| && currentSeriesShotMode != SERIES_SHOT_MODE_LLS |
| #endif |
| ) { |
| /* BURST */ |
| m_sCaptureMgr->setMultiCaptureMode(true); |
| captureIntent = AA_CAPTURE_INTENT_STILL_CAPTURE_OIS_MULTI; |
| } |
| #ifdef SAMSUNG_LBP |
| else if (currentSeriesShotMode == SERIES_SHOT_MODE_NONE && m_isLBPon == true |
| #ifdef LLS_REPROCESSING |
| && currentSeriesShotMode != SERIES_SHOT_MODE_LLS) |
| #endif |
| { |
| /* BEST PICK */ |
| m_sCaptureMgr->setMultiCaptureMode(true); |
| m_sCaptureMgr->setBestMultiCaptureMode(true); |
| captureIntent = AA_CAPTURE_INTENT_STILL_CAPTURE_OIS_BEST; |
| } |
| #endif |
| else { |
| /* SINGLE */ |
| #ifdef SAMSUNG_DEBLUR |
| if(m_exynosCameraParameters->getLDCaptureMode() == MULTI_SHOT_MODE_DEBLUR) { |
| captureIntent = AA_CAPTRUE_INTENT_STILL_CAPTURE_OIS_DEBLUR; |
| CLOGD("DEBUG(%s[%d]): start set Deblur mode captureIntent(%d)", __FUNCTION__, __LINE__,captureIntent); |
| } else |
| #endif |
| { |
| #ifdef SAMSUNG_LLS_DEBLUR |
| if (m_exynosCameraParameters->getLDCaptureMode() > 0 |
| && m_exynosCameraParameters->getLDCaptureMode() != MULTI_SHOT_MODE_DEBLUR) { |
| unsigned int captureintent = AA_CAPTRUE_INTENT_STILL_CAPTURE_DYNAMIC_SHOT; |
| unsigned int capturecount = m_exynosCameraParameters->getLDCaptureCount(); |
| unsigned int mask = 0; |
| |
| mask = (((captureintent << 16) & 0xFFFF0000) | ((capturecount << 0) & 0x0000FFFF)); |
| captureIntent = mask; |
| CLOGD("DEBUG(%s[%d]): start set multi mode captureIntent(%d)", __FUNCTION__, __LINE__,captureIntent); |
| } else |
| #endif |
| { |
| captureIntent = AA_CAPTURE_INTENT_STILL_CAPTURE_OIS_SINGLE; |
| } |
| } |
| } |
| |
| /* HACK: For the fast OIS-Capture Response time */ |
| ret = m_previewFrameFactory->setControl(V4L2_CID_IS_INTENT, captureIntent, PIPE_3AA); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):setControl(STILL_CAPTURE_OIS) fail. ret(%d) intent(%d)", |
| __FUNCTION__, __LINE__, ret, captureIntent); |
| |
| if(m_exynosCameraParameters->getSeriesShotCount() == 0) { |
| m_OISCaptureShutterEnabled = true; |
| } |
| |
| m_sCaptureMgr->setCaptureStep(ExynosCameraActivitySpecialCapture::SCAPTURE_STEP_START); |
| m_exynosCameraActivityControl->setOISCaptureMode(true); |
| } |
| #endif |
| else { |
| if (m_exynosCameraParameters->getCaptureExposureTime() != 0) { |
| m_stopLongExposure = false; |
| m_exynosCameraParameters->setExposureTime(); |
| } |
| } |
| #ifdef SET_LLS_CAPTURE_SETFILE |
| if(getCameraId() == CAMERA_ID_BACK && currentSeriesShotMode == SERIES_SHOT_MODE_LLS |
| #ifdef SR_CAPTURE |
| && !m_exynosCameraParameters->getSROn() |
| #endif |
| #ifdef FLASHED_LLS_CAPTURE |
| && !m_captureSelector->getFlashedLLSCaptureStatus() |
| #endif |
| ) { |
| CLOGD("DEBUG(%s[%d]): set LLS Capture mode on", __FUNCTION__, __LINE__); |
| m_exynosCameraParameters->setLLSCaptureOn(true); |
| } |
| #endif |
| #endif /* RAWDUMP_CAPTURE */ |
| #ifdef SAMSUNG_LBP |
| if(currentSeriesShotMode == SERIES_SHOT_MODE_NONE && m_isLBPon == true) { |
| int TotalBufferNum = (int)m_exynosCameraParameters->getHoldFrameCount(); |
| ret = uni_plugin_set(m_LBPpluginHandle, BESTPHOTO_PLUGIN_NAME, UNI_PLUGIN_INDEX_TOTAL_BUFFER_NUM, &TotalBufferNum); |
| if(ret < 0) { |
| CLOGE("[LBP](%s[%d]):Bestphoto plugin set failed!!", __FUNCTION__, __LINE__); |
| } |
| ret = uni_plugin_init(m_LBPpluginHandle); |
| if(ret < 0) { |
| CLOGE("[LBP](%s[%d]):Bestphoto plugin init failed!!", __FUNCTION__, __LINE__); |
| } |
| |
| m_LBPThread->run(PRIORITY_DEFAULT); |
| } |
| #endif |
| |
| #ifndef RAWDUMP_CAPTURE |
| if (currentSeriesShotMode == SERIES_SHOT_MODE_NONE && m_flashMgr->getNeedCaptureFlash() == false |
| && m_exynosCameraParameters->getCaptureExposureTime() == 0 |
| #ifdef OIS_CAPTURE |
| && m_exynosCameraParameters->getOISCaptureModeOn() == false |
| #endif |
| #ifdef SAMSUNG_LBP |
| && !m_isLBPon |
| #endif |
| ) { |
| m_isZSLCaptureOn = true; |
| } |
| #endif |
| |
| #ifndef RAWDUMP_CAPTURE |
| if (m_exynosCameraParameters->getSamsungCamera() |
| #if defined(SAMSUNG_DEBLUR) || defined(SAMSUNG_LLS_DEBLUR) |
| && !m_exynosCameraParameters->getLDCaptureMode() |
| #endif |
| ) { |
| int thumbnailW = 0, thumbnailH = 0; |
| m_exynosCameraParameters->getThumbnailSize(&thumbnailW, &thumbnailH); |
| |
| if ((thumbnailW > 0 && thumbnailH > 0) |
| && !m_exynosCameraParameters->getRecordingHint() |
| && !m_exynosCameraParameters->getDualMode() |
| && currentSeriesShotMode != SERIES_SHOT_MODE_LLS |
| #ifdef SAMSUNG_MAGICSHOT |
| && m_exynosCameraParameters->getShotMode() != SHOT_MODE_MAGIC |
| #endif |
| && m_exynosCameraParameters->getShotMode() != SHOT_MODE_OUTFOCUS |
| && m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_POSTVIEW_FRAME)) { |
| m_exynosCameraParameters->setIsThumbnailCallbackOn(true); |
| CLOGI("INFO(%s[%d]): m_isThumbnailCallbackOn(%d)", __FUNCTION__, __LINE__, |
| m_exynosCameraParameters->getIsThumbnailCallbackOn()); |
| } |
| } |
| #endif |
| |
| m_exynosCameraParameters->setSetfileYuvRange(); |
| |
| #if defined(SAMSUNG_DEBLUR) || defined(SAMSUNG_LLS_DEBLUR) |
| int pictureCount = m_exynosCameraParameters->getLDCaptureCount(); |
| |
| if(m_exynosCameraParameters->getLDCaptureMode()) { |
| m_reprocessingCounter.setCount(pictureCount); |
| } else |
| #endif |
| { |
| m_reprocessingCounter.setCount(seriesShotCount); |
| } |
| |
| if (m_prePictureThread->isRunning() == false) { |
| if (m_prePictureThread->run(PRIORITY_DEFAULT) != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):couldn't run pre-picture thread", __FUNCTION__, __LINE__); |
| return INVALID_OPERATION; |
| } |
| } |
| |
| #if defined(SAMSUNG_DEBLUR) || defined(SAMSUNG_LLS_DEBLUR) |
| if(m_exynosCameraParameters->getLDCaptureMode()) { |
| m_jpegCounter.setCount(seriesShotCount); |
| m_pictureCounter.setCount(pictureCount); |
| CLOGD("LDC(%s[%d]): pictureCount(%d), getLDCaptureMode(%d)", |
| __FUNCTION__, __LINE__, pictureCount, m_exynosCameraParameters->getLDCaptureMode()); |
| } else |
| #endif |
| { |
| m_jpegCounter.setCount(seriesShotCount); |
| m_pictureCounter.setCount(seriesShotCount); |
| } |
| |
| if (m_exynosCameraParameters->getCaptureExposureTime() <= CAMERA_PREVIEW_EXPOSURE_TIME_LIMIT) { |
| if (m_pictureThread->isRunning() == false) |
| ret = m_pictureThread->run(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):couldn't run picture thread, ret(%d)", __FUNCTION__, __LINE__, ret); |
| return INVALID_OPERATION; |
| } |
| } |
| |
| /* HDR, LLS, SIS should make YUV callback data. so don't use jpeg thread */ |
| if (!(m_hdrEnabled == true || |
| currentSeriesShotMode == SERIES_SHOT_MODE_LLS || |
| currentSeriesShotMode == SERIES_SHOT_MODE_SIS || |
| m_exynosCameraParameters->getShotMode() == SHOT_MODE_FRONT_PANORAMA)) { |
| m_jpegCallbackThread->join(); |
| if (m_exynosCameraParameters->getCaptureExposureTime() <= CAMERA_PREVIEW_EXPOSURE_TIME_LIMIT) { |
| ret = m_jpegCallbackThread->run(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):couldn't run jpeg callback thread, ret(%d)", __FUNCTION__, __LINE__, ret); |
| return INVALID_OPERATION; |
| } |
| } |
| } |
| } else { |
| /* HDR, LLS, SIS should make YUV callback data. so don't use jpeg thread */ |
| /* One second burst capture launching jpegCallbackThread automatically */ |
| if (!(m_hdrEnabled == true || |
| currentSeriesShotMode == SERIES_SHOT_MODE_LLS || |
| currentSeriesShotMode == SERIES_SHOT_MODE_SIS || |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| currentSeriesShotMode == SERIES_SHOT_MODE_ONE_SECOND_BURST || |
| #endif |
| m_exynosCameraParameters->getShotMode() == SHOT_MODE_FRONT_PANORAMA)) { |
| /* series shot : push buffer to callback thread. */ |
| m_jpegCallbackThread->join(); |
| ret = m_jpegCallbackThread->run(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):couldn't run jpeg callback thread, ret(%d)", __FUNCTION__, __LINE__, ret); |
| return INVALID_OPERATION; |
| } |
| } |
| CLOGI("INFO(%s[%d]): series shot takePicture, takePictureCount(%d)", |
| __FUNCTION__, __LINE__, m_takePictureCounter.getCount()); |
| m_takePictureCounter.decCount(); |
| |
| /* TODO : in case of no reprocesssing, we make zsl scheme or increse buf */ |
| if (m_exynosCameraParameters->isReprocessing() == false) |
| m_pictureEnabled = true; |
| } |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::cancelPicture() |
| { |
| CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__); |
| |
| if (m_exynosCameraParameters == NULL) { |
| CLOGE("ERR(%s):m_exynosCameraParameters is NULL", __FUNCTION__); |
| return NO_ERROR; |
| } |
| |
| if (m_exynosCameraParameters->getVisionMode() == true) { |
| CLOGW("WRN(%s[%d]): Vision mode does not support", __FUNCTION__, __LINE__); |
| /* android_printAssert(NULL, LOG_TAG, "Cannot support this operation"); */ |
| |
| return NO_ERROR; |
| } |
| |
| if (m_exynosCameraParameters->getLongExposureShotCount() > 0) { |
| CLOGD("DEBUG(%s[%d]):emergency stop for manual exposure shot", __FUNCTION__, __LINE__); |
| m_cancelPicture = true; |
| m_exynosCameraParameters->setPreviewExposureTime(); |
| m_pictureEnabled = false; |
| m_stopLongExposure = true; |
| m_reprocessingCounter.clearCount(); |
| m_clearJpegCallbackThread(false); |
| m_cancelPicture = false; |
| } |
| |
| /* |
| m_takePictureCounter.clearCount(); |
| m_reprocessingCounter.clearCount(); |
| m_pictureCounter.clearCount(); |
| m_jpegCounter.clearCount(); |
| */ |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::setParameters(const CameraParameters& params) |
| { |
| status_t ret = NO_ERROR; |
| CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__); |
| |
| #ifdef SCALABLE_ON |
| m_exynosCameraParameters->setScalableSensorMode(true); |
| #else |
| m_exynosCameraParameters->setScalableSensorMode(false); |
| #endif |
| |
| ret = m_exynosCameraParameters->setParameters(params); |
| #if 1 |
| /* HACK Reset Preview Flag*/ |
| if (m_exynosCameraParameters->getRestartPreview() == true && m_previewEnabled == true) { |
| m_resetPreview = true; |
| #ifdef SUPPORT_SW_VDIS |
| if(!m_swVDIS_Mode) |
| #endif /*SUPPORT_SW_VDIS*/ |
| ret = m_restartPreviewInternal(); |
| m_resetPreview = false; |
| CLOGI("INFO(%s[%d]) m_resetPreview(%d)", __FUNCTION__, __LINE__, m_resetPreview); |
| |
| if (ret < 0) |
| CLOGE("(%s[%d]): restart preview internal fail", __FUNCTION__, __LINE__); |
| } |
| #endif |
| |
| #ifdef CAMERA_FAST_ENTRANCE_V1 |
| if ((m_isFirstParametersSet == false) && |
| (m_exynosCameraParameters->getSamsungCamera() == true) && |
| (m_exynosCameraParameters->getDualMode() == false) && |
| (m_exynosCameraParameters->getVisionMode() == false)) { |
| CLOGD("DEBUG(%s[%d]):1st setParameters", __FUNCTION__, __LINE__); |
| m_fastEntrance = true; |
| m_isFirstParametersSet = true; |
| m_fastenAeThread->run(); |
| } |
| #endif |
| |
| return ret; |
| |
| } |
| |
| CameraParameters ExynosCamera::getParameters() const |
| { |
| CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__); |
| |
| return m_exynosCameraParameters->getParameters(); |
| } |
| |
| int ExynosCamera::getMaxNumDetectedFaces(void) |
| { |
| return m_exynosCameraParameters->getMaxNumDetectedFaces(); |
| } |
| |
| bool ExynosCamera::m_startFaceDetection(bool toggle) |
| { |
| CLOGD("DEBUG(%s[%d]) toggle : %d", __FUNCTION__, __LINE__, toggle); |
| |
| if (toggle == true) { |
| m_exynosCameraParameters->setFdEnable(true); |
| m_exynosCameraParameters->setFdMode(FACEDETECT_MODE_FULL); |
| } else { |
| m_exynosCameraParameters->setFdEnable(false); |
| m_exynosCameraParameters->setFdMode(FACEDETECT_MODE_OFF); |
| } |
| |
| memset(&m_frameMetadata, 0, sizeof(camera_frame_metadata_t)); |
| |
| return true; |
| } |
| |
| bool ExynosCamera::startFaceDetection(void) |
| { |
| if (m_flagStartFaceDetection == true) { |
| CLOGD("DEBUG(%s):Face detection already started..", __FUNCTION__); |
| return true; |
| } |
| |
| /* FD-AE is always on */ |
| #ifdef USE_FD_AE |
| #else |
| m_startFaceDetection(true); |
| #endif |
| |
| /* Block FD-AF except for special shot modes */ |
| if(m_exynosCameraParameters->getShotMode() == SHOT_MODE_BEAUTY_FACE || |
| m_exynosCameraParameters->getShotMode() == SHOT_MODE_SELFIE_ALARM) { |
| ExynosCameraActivityAutofocus *autoFocusMgr = m_exynosCameraActivityControl->getAutoFocusMgr(); |
| |
| if (autoFocusMgr->setFaceDetection(true) == false) { |
| CLOGE("ERR(%s[%d]):setFaceDetection(%d)", __FUNCTION__, __LINE__, true); |
| } else { |
| /* restart CAF when FD mode changed */ |
| switch (autoFocusMgr->getAutofocusMode()) { |
| case ExynosCameraActivityAutofocus::AUTOFOCUS_MODE_CONTINUOUS_PICTURE: |
| case ExynosCameraActivityAutofocus::AUTOFOCUS_MODE_CONTINUOUS_PICTURE_MACRO: |
| if (autoFocusMgr->flagAutofocusStart() == true && |
| autoFocusMgr->flagLockAutofocus() == false) { |
| autoFocusMgr->stopAutofocus(); |
| autoFocusMgr->startAutofocus(); |
| } |
| break; |
| default: |
| break; |
| } |
| } |
| } |
| |
| if (m_facedetectQ->getSizeOfProcessQ() > 0) { |
| CLOGE("ERR(%s[%d]):startFaceDetection recordingQ(%d)", __FUNCTION__, __LINE__, m_facedetectQ->getSizeOfProcessQ()); |
| /* |
| * just empty q on m_facedetectQ. |
| * m_clearList() can make deadlock by accessing frame |
| * deleted on stopPreview() |
| */ |
| /* m_clearList(m_facedetectQ); */ |
| m_facedetectQ->release(); |
| } |
| |
| m_flagStartFaceDetection = true; |
| |
| if (m_facedetectThread->isRunning() == false) |
| m_facedetectThread->run(); |
| |
| return true; |
| } |
| |
| bool ExynosCamera::stopFaceDetection(void) |
| { |
| if (m_flagStartFaceDetection == false) { |
| CLOGD("DEBUG(%s [%d]):Face detection already stopped..", __FUNCTION__, __LINE__); |
| return true; |
| } |
| |
| ExynosCameraActivityAutofocus *autoFocusMgr = m_exynosCameraActivityControl->getAutoFocusMgr(); |
| |
| if (autoFocusMgr->setFaceDetection(false) == false) { |
| CLOGE("ERR(%s[%d]):setFaceDetection(%d)", __FUNCTION__, __LINE__, false); |
| } else { |
| /* restart CAF when FD mode changed */ |
| switch (autoFocusMgr->getAutofocusMode()) { |
| case ExynosCameraActivityAutofocus::AUTOFOCUS_MODE_CONTINUOUS_PICTURE: |
| case ExynosCameraActivityAutofocus::AUTOFOCUS_MODE_CONTINUOUS_PICTURE_MACRO: |
| if (autoFocusMgr->flagAutofocusStart() == true && |
| autoFocusMgr->flagLockAutofocus() == false) { |
| autoFocusMgr->stopAutofocus(); |
| autoFocusMgr->startAutofocus(); |
| } |
| break; |
| default: |
| break; |
| } |
| } |
| |
| /* FD-AE is always on */ |
| #ifdef USE_FD_AE |
| #else |
| m_startFaceDetection(false); |
| #endif |
| m_flagStartFaceDetection = false; |
| |
| return true; |
| } |
| |
| #ifdef SAMSUNG_DOF |
| bool ExynosCamera::startCurrentSet(void) |
| { |
| m_currentSetStart = true; |
| |
| return true; |
| } |
| |
| bool ExynosCamera::stopCurrentSet(void) |
| { |
| m_currentSetStart = false; |
| |
| return true; |
| } |
| #endif |
| |
| |
| bool ExynosCamera::m_getRecordingEnabled(void) |
| { |
| Mutex::Autolock lock(m_recordingStateLock); |
| return m_recordingEnabled; |
| } |
| |
| void ExynosCamera::m_setRecordingEnabled(bool enable) |
| { |
| Mutex::Autolock lock(m_recordingStateLock); |
| m_recordingEnabled = enable; |
| return; |
| } |
| |
| int ExynosCamera::m_calibratePosition(int w, int new_w, int pos) |
| { |
| return (float)(pos * new_w) / (float)w; |
| } |
| |
| #ifdef SAMSUNG_DOF |
| void ExynosCamera::m_clearDOFmeta(void) |
| { |
| if(m_frameMetadata.dof_data != NULL) { |
| delete []m_frameMetadata.dof_data; |
| m_frameMetadata.dof_data = NULL; |
| } |
| m_frameMetadata.dof_column = 0; |
| m_frameMetadata.dof_row = 0; |
| |
| memset(&m_frameMetadata.current_set_data, 0, sizeof(camera_current_set_t)); |
| memset(&m_frameMetadata.single_paf_data, 0, sizeof(st_AF_PafWinResult)); |
| |
| m_flagMetaDataSet = false; |
| } |
| #endif |
| |
| #ifdef SAMSUNG_OT |
| void ExynosCamera::m_clearOTmeta(void) |
| { |
| memset(&m_frameMetadata.object_data, 0, sizeof(camera_object_t)); |
| } |
| #endif |
| |
| bool ExynosCamera::m_facedetectThreadFunc(void) |
| { |
| int32_t status = 0; |
| bool ret = true; |
| |
| int index = 0; |
| int count = 0; |
| |
| ExynosCameraFrame *newFrame = NULL; |
| uint32_t frameCnt = 0; |
| |
| if (m_previewEnabled == false) { |
| CLOGD("DEBUG(%s):preview is stopped, thread stop", __FUNCTION__); |
| ret = false; |
| goto func_exit; |
| } |
| |
| status = m_facedetectQ->waitAndPopProcessQ(&newFrame); |
| if (m_flagThreadStop == true) { |
| CLOGI("INFO(%s[%d]):m_flagThreadStop(%d) m_flagStartFaceDetection(%d)", __FUNCTION__, __LINE__, m_flagThreadStop, m_flagStartFaceDetection); |
| ret = false; |
| goto func_exit; |
| } |
| |
| if (status < 0) { |
| if (status == TIMED_OUT) { |
| /* Face Detection time out is not meaningful */ |
| } else { |
| /* TODO: doing exception handling */ |
| CLOGE("ERR(%s):wait and pop fail, ret(%d)", __FUNCTION__, ret); |
| } |
| goto func_exit; |
| } |
| |
| count = m_facedetectQ->getSizeOfProcessQ(); |
| if (count >= MAX_FACEDETECT_THREADQ_SIZE) { |
| if (newFrame != NULL) { |
| CLOGE("ERR(%s[%d]):m_facedetectQ skipped QSize(%d) frame(%d)", __FUNCTION__, __LINE__, count, newFrame->getFrameCount()); |
| newFrame->decRef(); |
| m_frameMgr->deleteFrame(newFrame); |
| newFrame = NULL; |
| } |
| for (int i = 0 ; i < count-1 ; i++) { |
| m_facedetectQ->popProcessQ(&newFrame); |
| if (newFrame != NULL) { |
| newFrame->decRef(); |
| m_frameMgr->deleteFrame(newFrame); |
| newFrame = NULL; |
| } |
| } |
| m_facedetectQ->popProcessQ(&newFrame); |
| } |
| |
| if (newFrame != NULL) { |
| status = m_doFdCallbackFunc(newFrame); |
| if (status < 0) { |
| CLOGE("ERR(%s[%d]) m_doFdCallbackFunc failed(%d).", __FUNCTION__, __LINE__, status); |
| } |
| } |
| |
| if (m_facedetectQ->getSizeOfProcessQ() > 0) { |
| ret = true; |
| } |
| |
| if (newFrame != NULL) { |
| newFrame->decRef(); |
| m_frameMgr->deleteFrame(newFrame); |
| newFrame = NULL; |
| } |
| |
| func_exit: |
| |
| return ret; |
| } |
| |
| #ifdef SR_CAPTURE |
| status_t ExynosCamera::m_doSRCallbackFunc(ExynosCameraFrame *frame) |
| { |
| ExynosCameraDurationTimer m_srcallbackTimer; |
| long long m_srcallbackTimerTime; |
| int pictureW, pictureH; |
| |
| CLOGI("INFO(%s[%d]) -IN-", __FUNCTION__, __LINE__); |
| |
| int id[NUM_OF_DETECTED_FACES]; |
| int score[NUM_OF_DETECTED_FACES]; |
| ExynosRect2 detectedFace[NUM_OF_DETECTED_FACES]; |
| ExynosRect2 detectedLeftEye[NUM_OF_DETECTED_FACES]; |
| ExynosRect2 detectedRightEye[NUM_OF_DETECTED_FACES]; |
| ExynosRect2 detectedMouth[NUM_OF_DETECTED_FACES]; |
| int numOfDetectedFaces = 0; |
| int num = 0; |
| int previewW, previewH; |
| |
| memset(&id, 0x00, sizeof(int) * NUM_OF_DETECTED_FACES); |
| memset(&score, 0x00, sizeof(int) * NUM_OF_DETECTED_FACES); |
| |
| m_exynosCameraParameters->getHwPreviewSize(&previewW, &previewH); |
| |
| int waitCount = 5; |
| while (m_isCopySrMdeta && 0 < waitCount) { |
| usleep(10000); |
| waitCount--; |
| } |
| |
| CLOGD("DEBUG(%s[%d]) faceDetectMode(%d)", __FUNCTION__, __LINE__, m_srShotMeta.stats.faceDetectMode); |
| CLOGV("[%d %d]", m_srShotMeta.stats.faceRectangles[0][0], m_srShotMeta.stats.faceRectangles[0][1]); |
| CLOGV("[%d %d]", m_srShotMeta.stats.faceRectangles[0][2], m_srShotMeta.stats.faceRectangles[0][3]); |
| |
| num = NUM_OF_DETECTED_FACES; |
| if (getMaxNumDetectedFaces() < num) |
| num = getMaxNumDetectedFaces(); |
| |
| switch (m_srShotMeta.stats.faceDetectMode) { |
| case FACEDETECT_MODE_SIMPLE: |
| case FACEDETECT_MODE_FULL: |
| break; |
| case FACEDETECT_MODE_OFF: |
| default: |
| num = 0; |
| break; |
| } |
| |
| for (int i = 0; i < num; i++) { |
| if (m_srShotMeta.stats.faceIds[i]) { |
| switch (m_srShotMeta.stats.faceDetectMode) { |
| case FACEDETECT_MODE_OFF: |
| break; |
| case FACEDETECT_MODE_SIMPLE: |
| detectedFace[i].x1 = m_srShotMeta.stats.faceRectangles[i][0]; |
| detectedFace[i].y1 = m_srShotMeta.stats.faceRectangles[i][1]; |
| detectedFace[i].x2 = m_srShotMeta.stats.faceRectangles[i][2]; |
| detectedFace[i].y2 = m_srShotMeta.stats.faceRectangles[i][3]; |
| numOfDetectedFaces++; |
| break; |
| case FACEDETECT_MODE_FULL: |
| id[i] = m_srShotMeta.stats.faceIds[i]; |
| score[i] = m_srShotMeta.stats.faceScores[i]; |
| |
| detectedFace[i].x1 = m_srShotMeta.stats.faceRectangles[i][0]; |
| detectedFace[i].y1 = m_srShotMeta.stats.faceRectangles[i][1]; |
| detectedFace[i].x2 = m_srShotMeta.stats.faceRectangles[i][2]; |
| detectedFace[i].y2 = m_srShotMeta.stats.faceRectangles[i][3]; |
| |
| detectedLeftEye[i].x1 |
| = detectedLeftEye[i].y1 |
| = detectedLeftEye[i].x2 |
| = detectedLeftEye[i].y2 = -1; |
| |
| detectedRightEye[i].x1 |
| = detectedRightEye[i].y1 |
| = detectedRightEye[i].x2 |
| = detectedRightEye[i].y2 = -1; |
| |
| detectedMouth[i].x1 |
| = detectedMouth[i].y1 |
| = detectedMouth[i].x2 |
| = detectedMouth[i].y2 = -1; |
| |
| numOfDetectedFaces++; |
| break; |
| default: |
| break; |
| } |
| } |
| } |
| |
| if (0 < numOfDetectedFaces) { |
| /* |
| * camera.h |
| * width : -1000~1000 |
| * height : -1000~1000 |
| * if eye, mouth is not detectable : -2000, -2000. |
| */ |
| memset(m_faces_sr, 0, sizeof(camera_face_t) * NUM_OF_DETECTED_FACES); |
| |
| int realNumOfDetectedFaces = 0; |
| |
| for (int i = 0; i < numOfDetectedFaces; i++) { |
| /* |
| * over 50s, we will catch |
| * if (score[i] < 50) |
| * continue; |
| */ |
| m_faces_sr[realNumOfDetectedFaces].rect[0] = m_calibratePosition(previewW, 2000, detectedFace[i].x1) - 1000; |
| m_faces_sr[realNumOfDetectedFaces].rect[1] = m_calibratePosition(previewH, 2000, detectedFace[i].y1) - 1000; |
| m_faces_sr[realNumOfDetectedFaces].rect[2] = m_calibratePosition(previewW, 2000, detectedFace[i].x2) - 1000; |
| m_faces_sr[realNumOfDetectedFaces].rect[3] = m_calibratePosition(previewH, 2000, detectedFace[i].y2) - 1000; |
| |
| m_faces_sr[realNumOfDetectedFaces].id = id[i]; |
| m_faces_sr[realNumOfDetectedFaces].score = score[i] > 100 ? 100 : score[i]; |
| |
| m_faces_sr[realNumOfDetectedFaces].left_eye[0] = (detectedLeftEye[i].x1 < 0) ? -2000 : m_calibratePosition(previewW, 2000, detectedLeftEye[i].x1) - 1000; |
| m_faces_sr[realNumOfDetectedFaces].left_eye[1] = (detectedLeftEye[i].y1 < 0) ? -2000 : m_calibratePosition(previewH, 2000, detectedLeftEye[i].y1) - 1000; |
| |
| m_faces_sr[realNumOfDetectedFaces].right_eye[0] = (detectedRightEye[i].x1 < 0) ? -2000 : m_calibratePosition(previewW, 2000, detectedRightEye[i].x1) - 1000; |
| m_faces_sr[realNumOfDetectedFaces].right_eye[1] = (detectedRightEye[i].y1 < 0) ? -2000 : m_calibratePosition(previewH, 2000, detectedRightEye[i].y1) - 1000; |
| |
| m_faces_sr[realNumOfDetectedFaces].mouth[0] = (detectedMouth[i].x1 < 0) ? -2000 : m_calibratePosition(previewW, 2000, detectedMouth[i].x1) - 1000; |
| m_faces_sr[realNumOfDetectedFaces].mouth[1] = (detectedMouth[i].y1 < 0) ? -2000 : m_calibratePosition(previewH, 2000, detectedMouth[i].y1) - 1000; |
| |
| CLOGV("face posision(cal:%d,%d %dx%d)(org:%d,%d %dx%d), id(%d), score(%d)", |
| m_faces_sr[realNumOfDetectedFaces].rect[0], m_faces_sr[realNumOfDetectedFaces].rect[1], |
| m_faces_sr[realNumOfDetectedFaces].rect[2], m_faces_sr[realNumOfDetectedFaces].rect[3], |
| detectedFace[i].x1, detectedFace[i].y1, |
| detectedFace[i].x2, detectedFace[i].y2, |
| m_faces_sr[realNumOfDetectedFaces].id, |
| m_faces_sr[realNumOfDetectedFaces].score); |
| |
| CLOGV("DEBUG(%s[%d]): left eye(%d,%d), right eye(%d,%d), mouth(%dx%d), num of facese(%d)", |
| __FUNCTION__, __LINE__, |
| m_faces_sr[realNumOfDetectedFaces].left_eye[0], |
| m_faces_sr[realNumOfDetectedFaces].left_eye[1], |
| m_faces_sr[realNumOfDetectedFaces].right_eye[0], |
| m_faces_sr[realNumOfDetectedFaces].right_eye[1], |
| m_faces_sr[realNumOfDetectedFaces].mouth[0], |
| m_faces_sr[realNumOfDetectedFaces].mouth[1], |
| realNumOfDetectedFaces |
| ); |
| |
| realNumOfDetectedFaces++; |
| } |
| |
| m_sr_frameMetadata.number_of_faces = realNumOfDetectedFaces; |
| m_sr_frameMetadata.faces = m_faces_sr; |
| |
| m_faceDetected = true; |
| m_fdThreshold = 0; |
| } else { |
| if (m_faceDetected == true && m_fdThreshold < NUM_OF_DETECTED_FACES_THRESHOLD) { |
| /* waiting the unexpected fail about face detected */ |
| m_fdThreshold++; |
| } else { |
| if (0 < m_sr_frameMetadata.number_of_faces) |
| memset(m_faces_sr, 0, sizeof(camera_face_t) * NUM_OF_DETECTED_FACES); |
| |
| m_sr_frameMetadata.number_of_faces = 0; |
| m_sr_frameMetadata.faces = m_faces_sr; |
| m_fdThreshold = 0; |
| m_faceDetected = false; |
| } |
| } |
| |
| m_exynosCameraParameters->getPictureSize(&pictureW, &pictureH); |
| |
| m_sr_frameMetadata.crop_info.org_width = pictureW; |
| m_sr_frameMetadata.crop_info.org_height = pictureH; |
| m_sr_frameMetadata.crop_info.cropped_width = m_sr_cropped_width; |
| m_sr_frameMetadata.crop_info.cropped_height = m_sr_cropped_height; |
| |
| CLOGI("INFO(%s[%d]):sieze (%d,%d,%d,%d)", __FUNCTION__, __LINE__ |
| , pictureW, pictureH, m_sr_cropped_width, m_sr_cropped_height); |
| |
| m_srcallbackTimer.start(); |
| |
| if (m_exynosCameraParameters->msgTypeEnabled(MULTI_FRAME_SHOT_SR_EXTRA_INFO)) |
| { |
| setBit(&m_callbackState, MULTI_FRAME_SHOT_SR_EXTRA_INFO, false); |
| m_dataCb(MULTI_FRAME_SHOT_SR_EXTRA_INFO, m_srCallbackHeap, 0, &m_sr_frameMetadata, m_callbackCookie); |
| clearBit(&m_callbackState, MULTI_FRAME_SHOT_SR_EXTRA_INFO, false); |
| } |
| m_srcallbackTimer.stop(); |
| m_srcallbackTimerTime = m_srcallbackTimer.durationUsecs(); |
| |
| if((int)m_srcallbackTimerTime / 1000 > 50) { |
| CLOGD("INFO(%s[%d]): SR callback duration time : (%d)mec", __FUNCTION__, __LINE__, (int)m_srcallbackTimerTime / 1000); |
| } |
| |
| return NO_ERROR; |
| } |
| #endif |
| |
| status_t ExynosCamera::m_doFdCallbackFunc(ExynosCameraFrame *frame) |
| { |
| #ifdef SAMSUNG_DOF |
| ExynosCameraActivityAutofocus *autoFocusMgr = m_exynosCameraActivityControl->getAutoFocusMgr(); |
| #endif |
| #ifdef LLS_CAPTURE |
| int LLS_value = 0; |
| #endif |
| ExynosCameraDurationTimer m_fdcallbackTimer; |
| long long m_fdcallbackTimerTime; |
| |
| if (m_fdmeta_shot == NULL) { |
| CLOGE("ERR(%s[%d]) meta_shot_ext is null", __FUNCTION__, __LINE__); |
| return INVALID_OPERATION; |
| } |
| |
| memset(m_fdmeta_shot, 0x00, sizeof(struct camera2_shot_ext)); |
| if (frame->getDynamicMeta(m_fdmeta_shot) != NO_ERROR) { |
| CLOGE("ERR(%s[%d]) meta_shot_ext is null", __FUNCTION__, __LINE__); |
| return INVALID_OPERATION; |
| } |
| |
| frame->getUserDynamicMeta(m_fdmeta_shot); |
| |
| if (m_flagStartFaceDetection == true) { |
| int id[NUM_OF_DETECTED_FACES]; |
| int score[NUM_OF_DETECTED_FACES]; |
| ExynosRect2 detectedFace[NUM_OF_DETECTED_FACES]; |
| ExynosRect2 detectedLeftEye[NUM_OF_DETECTED_FACES]; |
| ExynosRect2 detectedRightEye[NUM_OF_DETECTED_FACES]; |
| ExynosRect2 detectedMouth[NUM_OF_DETECTED_FACES]; |
| int numOfDetectedFaces = 0; |
| int num = 0; |
| struct camera2_dm *dm = NULL; |
| int previewW, previewH; |
| |
| memset(&id, 0x00, sizeof(int) * NUM_OF_DETECTED_FACES); |
| memset(&score, 0x00, sizeof(int) * NUM_OF_DETECTED_FACES); |
| |
| m_exynosCameraParameters->getHwPreviewSize(&previewW, &previewH); |
| #ifdef SUPPORT_SW_VDIS |
| if(m_exynosCameraParameters->isSWVdisMode()) { |
| m_swVDIS_AdjustPreviewSize(&previewW, &previewH); |
| } |
| #endif /*SUPPORT_SW_VDIS*/ |
| |
| dm = &(m_fdmeta_shot->shot.dm); |
| if (dm == NULL) { |
| CLOGE("ERR(%s[%d]) dm data is null", __FUNCTION__, __LINE__); |
| return INVALID_OPERATION; |
| } |
| |
| CLOGV("DEBUG(%s[%d]) faceDetectMode(%d)", __FUNCTION__, __LINE__, dm->stats.faceDetectMode); |
| CLOGV("[%d %d]", dm->stats.faceRectangles[0][0], dm->stats.faceRectangles[0][1]); |
| CLOGV("[%d %d]", dm->stats.faceRectangles[0][2], dm->stats.faceRectangles[0][3]); |
| |
| num = NUM_OF_DETECTED_FACES; |
| if (getMaxNumDetectedFaces() < num) |
| num = getMaxNumDetectedFaces(); |
| |
| switch (dm->stats.faceDetectMode) { |
| case FACEDETECT_MODE_SIMPLE: |
| case FACEDETECT_MODE_FULL: |
| break; |
| case FACEDETECT_MODE_OFF: |
| default: |
| num = 0; |
| break; |
| } |
| |
| for (int i = 0; i < num; i++) { |
| if (dm->stats.faceIds[i]) { |
| switch (dm->stats.faceDetectMode) { |
| case FACEDETECT_MODE_OFF: |
| break; |
| case FACEDETECT_MODE_SIMPLE: |
| detectedFace[i].x1 = dm->stats.faceRectangles[i][0]; |
| detectedFace[i].y1 = dm->stats.faceRectangles[i][1]; |
| detectedFace[i].x2 = dm->stats.faceRectangles[i][2]; |
| detectedFace[i].y2 = dm->stats.faceRectangles[i][3]; |
| numOfDetectedFaces++; |
| break; |
| case FACEDETECT_MODE_FULL: |
| id[i] = dm->stats.faceIds[i]; |
| score[i] = dm->stats.faceScores[i]; |
| |
| detectedFace[i].x1 = dm->stats.faceRectangles[i][0]; |
| detectedFace[i].y1 = dm->stats.faceRectangles[i][1]; |
| detectedFace[i].x2 = dm->stats.faceRectangles[i][2]; |
| detectedFace[i].y2 = dm->stats.faceRectangles[i][3]; |
| |
| detectedLeftEye[i].x1 |
| = detectedLeftEye[i].y1 |
| = detectedLeftEye[i].x2 |
| = detectedLeftEye[i].y2 = -1; |
| |
| detectedRightEye[i].x1 |
| = detectedRightEye[i].y1 |
| = detectedRightEye[i].x2 |
| = detectedRightEye[i].y2 = -1; |
| |
| detectedMouth[i].x1 |
| = detectedMouth[i].y1 |
| = detectedMouth[i].x2 |
| = detectedMouth[i].y2 = -1; |
| |
| numOfDetectedFaces++; |
| break; |
| default: |
| break; |
| } |
| } |
| } |
| |
| if (0 < numOfDetectedFaces) { |
| /* |
| * camera.h |
| * width : -1000~1000 |
| * height : -1000~1000 |
| * if eye, mouth is not detectable : -2000, -2000. |
| */ |
| memset(m_faces, 0, sizeof(camera_face_t) * NUM_OF_DETECTED_FACES); |
| |
| int realNumOfDetectedFaces = 0; |
| |
| for (int i = 0; i < numOfDetectedFaces; i++) { |
| /* |
| * over 50s, we will catch |
| * if (score[i] < 50) |
| * continue; |
| */ |
| m_faces[realNumOfDetectedFaces].rect[0] = m_calibratePosition(previewW, 2000, detectedFace[i].x1) - 1000; |
| m_faces[realNumOfDetectedFaces].rect[1] = m_calibratePosition(previewH, 2000, detectedFace[i].y1) - 1000; |
| m_faces[realNumOfDetectedFaces].rect[2] = m_calibratePosition(previewW, 2000, detectedFace[i].x2) - 1000; |
| m_faces[realNumOfDetectedFaces].rect[3] = m_calibratePosition(previewH, 2000, detectedFace[i].y2) - 1000; |
| |
| m_faces[realNumOfDetectedFaces].id = id[i]; |
| m_faces[realNumOfDetectedFaces].score = score[i] > 100 ? 100 : score[i]; |
| |
| m_faces[realNumOfDetectedFaces].left_eye[0] = (detectedLeftEye[i].x1 < 0) ? -2000 : m_calibratePosition(previewW, 2000, detectedLeftEye[i].x1) - 1000; |
| m_faces[realNumOfDetectedFaces].left_eye[1] = (detectedLeftEye[i].y1 < 0) ? -2000 : m_calibratePosition(previewH, 2000, detectedLeftEye[i].y1) - 1000; |
| |
| m_faces[realNumOfDetectedFaces].right_eye[0] = (detectedRightEye[i].x1 < 0) ? -2000 : m_calibratePosition(previewW, 2000, detectedRightEye[i].x1) - 1000; |
| m_faces[realNumOfDetectedFaces].right_eye[1] = (detectedRightEye[i].y1 < 0) ? -2000 : m_calibratePosition(previewH, 2000, detectedRightEye[i].y1) - 1000; |
| |
| m_faces[realNumOfDetectedFaces].mouth[0] = (detectedMouth[i].x1 < 0) ? -2000 : m_calibratePosition(previewW, 2000, detectedMouth[i].x1) - 1000; |
| m_faces[realNumOfDetectedFaces].mouth[1] = (detectedMouth[i].y1 < 0) ? -2000 : m_calibratePosition(previewH, 2000, detectedMouth[i].y1) - 1000; |
| |
| CLOGV("face posision(cal:%d,%d %dx%d)(org:%d,%d %dx%d), id(%d), score(%d)", |
| m_faces[realNumOfDetectedFaces].rect[0], m_faces[realNumOfDetectedFaces].rect[1], |
| m_faces[realNumOfDetectedFaces].rect[2], m_faces[realNumOfDetectedFaces].rect[3], |
| detectedFace[i].x1, detectedFace[i].y1, |
| detectedFace[i].x2, detectedFace[i].y2, |
| m_faces[realNumOfDetectedFaces].id, |
| m_faces[realNumOfDetectedFaces].score); |
| |
| CLOGV("DEBUG(%s[%d]): left eye(%d,%d), right eye(%d,%d), mouth(%dx%d), num of facese(%d)", |
| __FUNCTION__, __LINE__, |
| m_faces[realNumOfDetectedFaces].left_eye[0], |
| m_faces[realNumOfDetectedFaces].left_eye[1], |
| m_faces[realNumOfDetectedFaces].right_eye[0], |
| m_faces[realNumOfDetectedFaces].right_eye[1], |
| m_faces[realNumOfDetectedFaces].mouth[0], |
| m_faces[realNumOfDetectedFaces].mouth[1], |
| realNumOfDetectedFaces |
| ); |
| |
| realNumOfDetectedFaces++; |
| } |
| |
| m_frameMetadata.number_of_faces = realNumOfDetectedFaces; |
| m_frameMetadata.faces = m_faces; |
| |
| m_faceDetected = true; |
| m_fdThreshold = 0; |
| } else { |
| if (m_faceDetected == true && m_fdThreshold < NUM_OF_DETECTED_FACES_THRESHOLD) { |
| /* waiting the unexpected fail about face detected */ |
| m_fdThreshold++; |
| } else { |
| if (0 < m_frameMetadata.number_of_faces) |
| memset(m_faces, 0, sizeof(camera_face_t) * NUM_OF_DETECTED_FACES); |
| |
| m_frameMetadata.number_of_faces = 0; |
| m_frameMetadata.faces = m_faces; |
| m_fdThreshold = 0; |
| m_faceDetected = false; |
| } |
| } |
| } else { |
| if (0 < m_frameMetadata.number_of_faces) |
| memset(m_faces, 0, sizeof(camera_face_t) * NUM_OF_DETECTED_FACES); |
| |
| m_frameMetadata.number_of_faces = 0; |
| m_frameMetadata.faces = m_faces; |
| |
| m_fdThreshold = 0; |
| |
| m_faceDetected = false; |
| } |
| |
| #ifdef LLS_CAPTURE |
| m_needLLS_history[3] = m_needLLS_history[2]; |
| m_needLLS_history[2] = m_needLLS_history[1]; |
| m_needLLS_history[1] = m_exynosCameraParameters->getLLS(m_fdmeta_shot); |
| |
| if ((m_needLLS_history[1] == m_needLLS_history[2])&& |
| (m_needLLS_history[1] == m_needLLS_history[3])) { |
| LLS_value = m_needLLS_history[0] = m_needLLS_history[1]; |
| } else { |
| LLS_value = m_needLLS_history[0]; |
| } |
| |
| m_exynosCameraParameters->setLLSValue(LLS_value); |
| |
| if (m_exynosCameraParameters->getShotMode() == SHOT_MODE_PRO_MODE) { |
| LLS_value = LLS_LEVEL_ZSL_LIKE; /* disable SR Mode */ |
| } else if (LLS_value >= LLS_LEVEL_MULTI_MERGE_INDICATOR_2 && LLS_value <= LLS_LEVEL_MULTI_MERGE_INDICATOR_4) { |
| LLS_value = LLS_LEVEL_LLS_INDICATOR_ONLY; |
| } |
| |
| m_frameMetadata.needLLS = LLS_value; |
| m_frameMetadata.light_condition = LLS_value; |
| |
| CLOGV("[%d[%d][%d][%d] LLS_value(%d) light_condition(%d)", |
| m_needLLS_history[0], m_needLLS_history[1], m_needLLS_history[2], m_needLLS_history[3], |
| m_exynosCameraParameters->getLLSValue(), m_frameMetadata.light_condition); |
| #endif |
| |
| #ifdef SAMSUNG_LBP |
| uint32_t shutterSpeed = 0; |
| |
| if(m_fdmeta_shot->shot.udm.ae.vendorSpecific[0] == 0xAEAEAEAE) |
| shutterSpeed = m_fdmeta_shot->shot.udm.ae.vendorSpecific[64]; |
| else |
| shutterSpeed = m_fdmeta_shot->shot.udm.internal.vendorSpecific2[100]; |
| |
| CLOGV("[LBP]: ShutterSpeed:%d", shutterSpeed); |
| if(shutterSpeed <= 24) |
| m_isLBPlux = true; |
| else |
| m_isLBPlux = false; |
| #endif |
| |
| #ifdef TOUCH_AE |
| if(((m_exynosCameraParameters->getMeteringMode() >= METERING_MODE_CENTER_TOUCH) |
| && (m_exynosCameraParameters->getMeteringMode() <= METERING_MODE_AVERAGE_TOUCH)) |
| && (m_fdmeta_shot->shot.udm.ae.vendorSpecific[395] == 1) /* touch ae State flag - 0:search 1:done */ |
| && (m_fdmeta_shot->shot.udm.ae.vendorSpecific[398] == 1) /* touch ae enable flag - 0:disable 1:enable */) { |
| m_notifyCb(AE_RESULT, 0, 0, m_callbackCookie); |
| CLOGV("INFO(%s[%d]): AE_RESULT(%d)", __FUNCTION__, __LINE__, m_fdmeta_shot->shot.dm.aa.aeState); |
| } |
| |
| m_frameMetadata.ae_bv_changed = m_fdmeta_shot->shot.udm.ae.vendorSpecific[396]; |
| #endif |
| |
| #ifdef SAMSUNG_DOF |
| if(autoFocusMgr->getCurrentState() == ExynosCameraActivityAutofocus::AUTOFOCUS_STATE_SCANNING || |
| m_currentSetStart == true) { |
| /* Single Window */ |
| m_frameMetadata.current_set_data.lens_position_min = (uint16_t)m_fdmeta_shot->shot.udm.af.lensPositionMacro; |
| m_frameMetadata.current_set_data.lens_position_max = (uint16_t)m_fdmeta_shot->shot.udm.af.lensPositionInfinity; |
| m_frameMetadata.current_set_data.lens_position_current = (uint16_t)m_fdmeta_shot->shot.udm.af.lensPositionCurrent; |
| m_frameMetadata.current_set_data.driver_resolution = m_fdmeta_shot->shot.udm.companion.pdaf.lensPosResolution; |
| CLOGV("current_set_data.exposure_time = %d", m_frameMetadata.current_set_data.exposure_time); |
| CLOGV("current_set_data.iso = %d", m_frameMetadata.current_set_data.iso); |
| CLOGV("current_set_data.lens_position_min = %d", m_frameMetadata.current_set_data.lens_position_min); |
| CLOGV("current_set_data.lens_position_max = %d", m_frameMetadata.current_set_data.lens_position_max); |
| CLOGV("current_set_data.lens_position_current = %d", m_frameMetadata.current_set_data.lens_position_current); |
| CLOGV("current_set_data.driver_resolution = %d", m_frameMetadata.current_set_data.driver_resolution); |
| |
| m_flagMetaDataSet = true; |
| } |
| |
| if(autoFocusMgr->getCurrentState() == ExynosCameraActivityAutofocus::AUTOFOCUS_STATE_SCANNING) { |
| m_frameMetadata.single_paf_data.mode = m_fdmeta_shot->shot.udm.companion.pdaf.singleResult.mode; |
| m_frameMetadata.single_paf_data.goal_pos = m_fdmeta_shot->shot.udm.companion.pdaf.singleResult.goalPos; |
| m_frameMetadata.single_paf_data.reliability = m_fdmeta_shot->shot.udm.companion.pdaf.singleResult.reliability; |
| CLOGV("single_paf_data.mode = %d", m_fdmeta_shot->shot.udm.companion.pdaf.singleResult.mode); |
| CLOGV("single_paf_data.goal_pos = %d", m_fdmeta_shot->shot.udm.companion.pdaf.singleResult.goalPos); |
| CLOGV("single_paf_data.reliability = %d", m_fdmeta_shot->shot.udm.companion.pdaf.singleResult.reliability); |
| } |
| |
| if (m_exynosCameraParameters->getShotMode() == SHOT_MODE_OUTFOCUS) { |
| if (m_fdmeta_shot->shot.udm.companion.pdaf.numCol > 0 && |
| m_fdmeta_shot->shot.udm.companion.pdaf.numRow > 0) { |
| if((autoFocusMgr->getCurrentState() == ExynosCameraActivityAutofocus::AUTOFOCUS_STATE_SUCCEESS || |
| autoFocusMgr->getCurrentState() == ExynosCameraActivityAutofocus::AUTOFOCUS_STATE_FAIL) && |
| m_AFstatus == ExynosCameraActivityAutofocus::AUTOFOCUS_STATE_SCANNING) { |
| /* Multi window */ |
| m_frameMetadata.dof_column = m_fdmeta_shot->shot.udm.companion.pdaf.numCol; |
| m_frameMetadata.dof_row = m_fdmeta_shot->shot.udm.companion.pdaf.numRow; |
| |
| if(m_frameMetadata.dof_data == NULL) |
| m_frameMetadata.dof_data = new st_AF_PafWinResult[m_frameMetadata.dof_column * m_frameMetadata.dof_row]; |
| for(int i = 0 ; i < m_frameMetadata.dof_column ; i++) { |
| memcpy(m_frameMetadata.dof_data + (i * m_frameMetadata.dof_row), m_fdmeta_shot->shot.udm.companion.pdaf.multiResult[i], |
| sizeof(camera2_pdaf_multi_result) * m_frameMetadata.dof_row); |
| } |
| |
| for(int i = 0; i < m_fdmeta_shot->shot.udm.companion.pdaf.numCol; i++){ |
| for(int j = 0; j < m_fdmeta_shot->shot.udm.companion.pdaf.numRow; j++){ |
| CLOGD("dof_data[%d][%d] mode = %d", i, j, (m_frameMetadata.dof_data+(i*m_frameMetadata.dof_row +j))->mode); |
| CLOGD("dof_data[%d][%d] goalPos = %d", i, j, (m_frameMetadata.dof_data+(i*m_frameMetadata.dof_row +j))->goal_pos); |
| CLOGD("dof_data[%d][%d] reliability = %d", i, j, (m_frameMetadata.dof_data+(i*m_frameMetadata.dof_row +j))->reliability); |
| } |
| } |
| |
| if (m_fdmeta_shot->shot.udm.ae.vendorSpecific[0] == 0xAEAEAEAE) |
| m_frameMetadata.current_set_data.exposure_time = (uint32_t)m_fdmeta_shot->shot.udm.ae.vendorSpecific[64]; |
| else |
| m_frameMetadata.current_set_data.exposure_time = (uint32_t)m_fdmeta_shot->shot.udm.internal.vendorSpecific2[100]; |
| |
| m_frameMetadata.current_set_data.iso = (uint16_t)m_fdmeta_shot->shot.udm.internal.vendorSpecific2[101]; |
| m_frameMetadata.current_set_data.lens_position_min = (uint16_t)m_fdmeta_shot->shot.udm.af.lensPositionMacro; |
| m_frameMetadata.current_set_data.lens_position_max = (uint16_t)m_fdmeta_shot->shot.udm.af.lensPositionInfinity; |
| m_frameMetadata.current_set_data.lens_position_current = (uint16_t)m_fdmeta_shot->shot.udm.af.lensPositionCurrent; |
| m_frameMetadata.current_set_data.driver_resolution = m_fdmeta_shot->shot.udm.companion.pdaf.lensPosResolution; |
| CLOGD("current_set_data.exposure_time = %d", m_frameMetadata.current_set_data.exposure_time); |
| CLOGD("current_set_data.iso = %d", m_frameMetadata.current_set_data.iso); |
| CLOGD("current_set_data.lens_position_min = %d", m_frameMetadata.current_set_data.lens_position_min); |
| CLOGD("current_set_data.lens_position_max = %d", m_frameMetadata.current_set_data.lens_position_max); |
| CLOGD("current_set_data.lens_position_current = %d", m_frameMetadata.current_set_data.lens_position_current); |
| CLOGD("current_set_data.driver_resolution = %d", m_frameMetadata.current_set_data.driver_resolution); |
| |
| m_flagMetaDataSet = true; |
| } |
| } |
| } else { |
| m_frameMetadata.current_set_data.exposure_time = (uint32_t)m_fdmeta_shot->shot.dm.sensor.exposureTime; |
| m_frameMetadata.current_set_data.exposure_value = (int16_t)m_fdmeta_shot->shot.dm.aa.vendor_exposureValue; |
| m_frameMetadata.current_set_data.iso = (uint16_t)m_fdmeta_shot->shot.dm.sensor.sensitivity; |
| CLOGV("current_set_data.exposure_time = %d", m_frameMetadata.current_set_data.exposure_time); |
| CLOGV("current_set_data.exposure_value = %d", m_frameMetadata.current_set_data.exposure_value); |
| CLOGV("current_set_data.iso = %d", m_frameMetadata.current_set_data.iso); |
| } |
| |
| m_AFstatus = autoFocusMgr->getCurrentState(); |
| #endif |
| |
| #ifdef SAMSUNG_OT |
| if (m_exynosCameraParameters->getObjectTrackingGet() == true){ |
| m_frameMetadata.object_data.focusState = m_OTfocusData.FocusState; |
| m_frameMetadata.object_data.focusROI[0] = m_OTfocusData.FocusROILeft; |
| m_frameMetadata.object_data.focusROI[1] = m_OTfocusData.FocusROITop; |
| m_frameMetadata.object_data.focusROI[2] = m_OTfocusData.FocusROIRight; |
| m_frameMetadata.object_data.focusROI[3] = m_OTfocusData.FocusROIBottom; |
| CLOGV("[OBTR](%s[%d])focusState: %d, focusROI[0]: %d, focusROI[1]: %d, focusROI[2]: %d, focusROI[3]: %d", |
| __FUNCTION__, __LINE__, m_OTfocusData.FocusState, |
| m_OTfocusData.FocusROILeft, m_OTfocusData.FocusROITop, |
| m_OTfocusData.FocusROIRight, m_OTfocusData.FocusROIBottom); |
| } |
| #endif |
| |
| #ifdef SAMSUNG_CAMERA_EXTRA_INFO |
| if (m_exynosCameraParameters->getFlashMode() == FLASH_MODE_AUTO) { |
| ExynosCameraActivityFlash *m_flashMgr = m_exynosCameraActivityControl->getFlashMgr(); |
| m_frameMetadata.flash_enabled = (int32_t) m_flashMgr->getNeedCaptureFlash(); |
| } else { |
| m_frameMetadata.flash_enabled = 0; |
| } |
| |
| if (m_exynosCameraParameters->getRTHdr() == COMPANION_WDR_AUTO) { |
| if (m_fdmeta_shot->shot.dm.stats.wdrAutoState == STATE_WDR_AUTO_REQUIRED) |
| m_frameMetadata.hdr_enabled = 1; |
| else |
| m_frameMetadata.hdr_enabled = 0; |
| } else { |
| m_frameMetadata.hdr_enabled = 0; |
| } |
| |
| m_frameMetadata.awb_exposure.brightness = m_fdmeta_shot->shot.udm.awb.vendorSpecific[11]; |
| m_frameMetadata.awb_exposure.colorTemp = m_fdmeta_shot->shot.udm.awb.vendorSpecific[21]; |
| m_frameMetadata.awb_exposure.awbRgbGain[0] = m_fdmeta_shot->shot.udm.awb.vendorSpecific[22]; |
| m_frameMetadata.awb_exposure.awbRgbGain[1] = m_fdmeta_shot->shot.udm.awb.vendorSpecific[23]; |
| m_frameMetadata.awb_exposure.awbRgbGain[2] = m_fdmeta_shot->shot.udm.awb.vendorSpecific[24]; |
| #endif |
| |
| m_fdcallbackTimer.start(); |
| |
| if (m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA) && |
| (m_flagStartFaceDetection || m_flagLLSStart || m_flagLightCondition |
| #ifdef SAMSUNG_CAMERA_EXTRA_INFO |
| || m_flagFlashCallback || m_flagHdrCallback |
| #endif |
| #ifdef SAMSUNG_DOF |
| || m_flagMetaDataSet |
| #endif |
| #ifdef SAMSUNG_OT |
| || m_exynosCameraParameters->getObjectTrackingGet() |
| #endif |
| )) |
| { |
| setBit(&m_callbackState, CALLBACK_STATE_PREVIEW_META, false); |
| m_dataCb(CAMERA_MSG_PREVIEW_METADATA, m_fdCallbackHeap, 0, &m_frameMetadata, m_callbackCookie); |
| clearBit(&m_callbackState, CALLBACK_STATE_PREVIEW_META, false); |
| } |
| m_fdcallbackTimer.stop(); |
| m_fdcallbackTimerTime = m_fdcallbackTimer.durationUsecs(); |
| |
| #ifdef SAMSUNG_DOF |
| m_clearDOFmeta(); |
| #endif |
| |
| if((int)m_fdcallbackTimerTime / 1000 > 50) { |
| CLOGD("INFO(%s[%d]): FD callback duration time : (%d)mec", __FUNCTION__, __LINE__, (int)m_fdcallbackTimerTime / 1000); |
| } |
| |
| return NO_ERROR; |
| } |
| |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| void ExynosCamera::m_clearOneSecondBurst(bool isJpegCallbackThread) |
| { |
| if (m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_ONE_SECOND_BURST) { |
| CLOGD("DEBUG(%s[%d]): DISABLE ONE SECOND BURST %d - TimeCheck", __FUNCTION__, __LINE__, isJpegCallbackThread); |
| |
| m_takePictureCounter.setCount(0); |
| #ifdef OIS_CAPTURE |
| if (getCameraId() == CAMERA_ID_BACK) { |
| ExynosCameraActivitySpecialCapture *m_sCaptureMgr = m_exynosCameraActivityControl->getSpecialCaptureMgr(); |
| m_sCaptureMgr->setCaptureStep(ExynosCameraActivitySpecialCapture::SCAPTURE_STEP_WAIT_CAPTURE); |
| } |
| #endif |
| |
| m_pictureEnabled = false; |
| m_one_second_burst_capture = false; |
| m_jpegCallbackCounter.clearCount(); |
| m_reprocessingCounter.clearCount(); |
| m_jpegCounter.clearCount(); |
| m_pictureCounter.clearCount(); |
| m_stopBurstShot = true; |
| if (isJpegCallbackThread) { |
| m_clearJpegCallbackThread(isJpegCallbackThread); |
| m_exynosCameraParameters->setSeriesShotMode(SERIES_SHOT_MODE_NONE); |
| #ifdef USE_DVFS_LOCK |
| if (m_exynosCameraParameters->getDvfsLock() == true) |
| m_exynosCameraParameters->setDvfsLock(false); |
| #endif |
| } else { |
| /* waiting jpegCallbackThread first. jpegCallbackThread will launching m_clearJpegCallbackThread() */ |
| CLOGI("INFO(%s[%d]): wait m_jpegCallbackThread", __FUNCTION__, __LINE__); |
| m_jpegCallbackThread->requestExit(); |
| m_jpegCallbackThread->requestExitAndWait(); |
| m_exynosCameraParameters->setSeriesShotMode(SERIES_SHOT_MODE_NONE); |
| } |
| |
| CLOGD("DEBUG(%s[%d]): DISABLE ONE SECOND BURST DONE %d - TimeCheck", __FUNCTION__, __LINE__, isJpegCallbackThread); |
| } |
| if (m_one_second_jpegCallbackHeap != NULL) { |
| m_one_second_jpegCallbackHeap->release(m_one_second_jpegCallbackHeap); |
| m_one_second_jpegCallbackHeap = NULL; |
| } |
| if (m_one_second_postviewCallbackHeap != NULL) { |
| m_one_second_postviewCallbackHeap->release(m_one_second_postviewCallbackHeap); |
| m_one_second_postviewCallbackHeap = NULL; |
| } |
| for (int i = 0; i < ONE_SECOND_BURST_CAPTURE_CHECK_COUNT; i++) |
| TakepictureDurationTime[i] = 0; |
| } |
| #endif |
| |
| status_t ExynosCamera::sendCommand(int32_t command, int32_t arg1, __unused int32_t arg2) |
| { |
| ExynosCameraActivityUCTL *uctlMgr = NULL; |
| #if defined(SAMSUNG_DOF) || defined(SAMSUNG_OT) |
| ExynosCameraActivityAutofocus *autoFocusMgr = m_exynosCameraActivityControl->getAutoFocusMgr(); |
| #endif |
| #ifdef SAMSUNG_OIS |
| int zoomLevel; |
| int zoomRatio; |
| #endif |
| |
| CLOGV("INFO(%s[%d])", __FUNCTION__, __LINE__); |
| |
| if (m_exynosCameraParameters != NULL) { |
| if (m_exynosCameraParameters->getVisionMode() == true) { |
| CLOGW("WRN(%s[%d]): Vision mode does not support", __FUNCTION__, __LINE__); |
| android_printAssert(NULL, LOG_TAG, "Cannot support this operation"); |
| |
| return INVALID_OPERATION; |
| } |
| |
| #ifdef SAMSUNG_OIS |
| zoomLevel = m_exynosCameraParameters->getZoomLevel(); |
| zoomRatio = m_exynosCameraParameters->getZoomRatio(zoomLevel); |
| #endif |
| } else { |
| CLOGE("ERR(%s):m_exynosCameraParameters is NULL", __FUNCTION__); |
| return INVALID_OPERATION; |
| } |
| |
| /* TO DO : implemented based on the command */ |
| switch(command) { |
| case CAMERA_CMD_START_FACE_DETECTION: |
| case CAMERA_CMD_STOP_FACE_DETECTION: |
| if (getMaxNumDetectedFaces() == 0) { |
| CLOGE("ERR(%s):getMaxNumDetectedFaces == 0", __FUNCTION__); |
| return BAD_VALUE; |
| } |
| |
| if (arg1 == CAMERA_FACE_DETECTION_SW) { |
| CLOGD("DEBUG(%s):only support HW face dectection", __FUNCTION__); |
| return BAD_VALUE; |
| } |
| |
| if (command == CAMERA_CMD_START_FACE_DETECTION) { |
| CLOGD("DEBUG(%s):CAMERA_CMD_START_FACE_DETECTION is called!", __FUNCTION__); |
| if (m_flagStartFaceDetection == false |
| && startFaceDetection() == false) { |
| CLOGE("ERR(%s):startFaceDetection() fail", __FUNCTION__); |
| return BAD_VALUE; |
| } |
| } else { |
| CLOGD("DEBUG(%s):CAMERA_CMD_STOP_FACE_DETECTION is called!", __FUNCTION__); |
| if ( m_flagStartFaceDetection == true |
| && stopFaceDetection() == false) { |
| CLOGE("ERR(%s):stopFaceDetection() fail", __FUNCTION__); |
| return BAD_VALUE; |
| } |
| } |
| break; |
| #ifdef SAMSUNG_OT |
| case 1504: /* HAL_OBJECT_TRACKING_STARTSTOP */ |
| CLOGD("DEBUG(%s):HAL_OBJECT_TRACKING_STARTSTOP(%d) is called!", __FUNCTION__, arg1); |
| if(arg1) { |
| /* Start case */ |
| int ret = uni_plugin_init(m_OTpluginHandle); |
| if(ret < 0) { |
| CLOGE("[OBTR](%s[%d]):Object Tracking plugin init failed!!", __FUNCTION__, __LINE__); |
| } |
| autoFocusMgr->setObjectTrackingStart(true); |
| m_OTstart = OBJECT_TRACKING_INIT; |
| } |
| else { |
| /* Stop case */ |
| autoFocusMgr->setObjectTrackingStart(false); |
| m_OTstart = OBJECT_TRACKING_DEINIT; |
| m_OTstatus = UNI_PLUGIN_OBJECT_TRACKING_IDLE; |
| m_OTisTouchAreaGet = false; |
| m_exynosCameraParameters->setObjectTrackingGet(false); |
| m_clearOTmeta(); |
| /* Waiting here in the recording mode can make preview thread stop */ |
| #if 0 |
| if(m_OTstart != OBJECT_TRACKING_IDLE) { |
| m_OT_mutex.lock(); |
| m_OTisWait = true; |
| m_OT_condition.waitRelative(m_OT_mutex, 1000000000); /* 1sec */ |
| m_OTisWait = false; |
| m_OT_mutex.unlock(); |
| } |
| CLOGD("DEBUG(%s):HAL_OBJECT_TRACKING_STARTSTOP(%d) Out is called!", __FUNCTION__, arg1); |
| #endif |
| } |
| break; |
| #endif |
| #ifdef BURST_CAPTURE |
| case 1571: /* HAL_CMD_RUN_BURST_TAKE */ |
| CLOGD("DEBUG(%s):HAL_CMD_RUN_BURST_TAKE is called!", __FUNCTION__); |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| m_clearOneSecondBurst(false); |
| #endif |
| |
| if( m_burstInitFirst ) { |
| m_burstRealloc = true; |
| m_burstInitFirst = false; |
| } |
| m_exynosCameraParameters->setSeriesShotMode(SERIES_SHOT_MODE_BURST); |
| m_exynosCameraParameters->setSeriesShotSaveLocation(arg1); |
| m_takePictureCounter.setCount(0); |
| |
| m_burstCaptureCallbackCount = 0; |
| |
| { |
| // Check jpeg save path |
| char default_path[20]; |
| int SeriesSaveLocation = m_exynosCameraParameters->getSeriesShotSaveLocation(); |
| |
| memset(default_path, 0, sizeof(default_path)); |
| |
| if (SeriesSaveLocation == BURST_SAVE_PHONE) |
| strncpy(default_path, CAMERA_SAVE_PATH_PHONE, sizeof(default_path)-1); |
| else if (SeriesSaveLocation == BURST_SAVE_SDCARD) |
| strncpy(default_path, CAMERA_SAVE_PATH_EXT, sizeof(default_path)-1); |
| |
| m_CheckCameraSavingPath(default_path, |
| m_exynosCameraParameters->getSeriesShotFilePath(), |
| m_burstSavePath, sizeof(m_burstSavePath)); |
| } |
| #ifdef SAMSUNG_BD |
| m_BDbufferIndex = 0; |
| if(m_BDpluginHandle != NULL && m_BDstatus != BLUR_DETECTION_INIT) { |
| int ret = uni_plugin_init(m_BDpluginHandle); |
| if(ret < 0) { |
| CLOGE("[BD](%s[%d]): Plugin init failed!!", __FUNCTION__, __LINE__); |
| } |
| for(int i = 0; i < MAX_BD_BUFF_NUM; i++) { |
| m_BDbuffer[i].data = new unsigned char[BD_EXIF_SIZE]; |
| } |
| } |
| m_BDstatus = BLUR_DETECTION_INIT; |
| #endif |
| #ifdef USE_DVFS_LOCK |
| m_exynosCameraParameters->setDvfsLock(true); |
| #endif |
| break; |
| case 1572: /* HAL_CMD_STOP_BURST_TAKE */ |
| CLOGD("DEBUG(%s):HAL_CMD_STOP_BURST_TAKE is called!", __FUNCTION__); |
| m_takePictureCounter.setCount(0); |
| |
| #ifdef OIS_CAPTURE |
| if (getCameraId() == CAMERA_ID_BACK) { |
| ExynosCameraActivitySpecialCapture *m_sCaptureMgr = m_exynosCameraActivityControl->getSpecialCaptureMgr(); |
| if (!m_exynosCameraParameters->getOISCaptureModeOn()) { |
| m_sCaptureMgr->setMultiCaptureMode(false); |
| } |
| /* setMultiCaptureMode flag will be disabled in SCAPTURE_STEP_END in case of OIS capture */ |
| m_sCaptureMgr->setCaptureStep(ExynosCameraActivitySpecialCapture::SCAPTURE_STEP_WAIT_CAPTURE); |
| m_exynosCameraParameters->setOISCaptureModeOn(false); |
| } |
| #endif |
| |
| if (m_exynosCameraParameters->getSeriesShotCount() == MAX_SERIES_SHOT_COUNT) { |
| m_reprocessingCounter.clearCount(); |
| m_pictureCounter.clearCount(); |
| m_jpegCounter.clearCount(); |
| } |
| |
| m_stopBurstShot = true; |
| |
| m_clearJpegCallbackThread(false); |
| |
| m_exynosCameraParameters->setSeriesShotMode(SERIES_SHOT_MODE_NONE); |
| #ifdef SAMSUNG_BD |
| m_BDbufferQ->release(); |
| |
| if(m_BDpluginHandle != NULL && m_BDstatus == BLUR_DETECTION_INIT) { |
| int ret = uni_plugin_deinit(m_BDpluginHandle); |
| if(ret < 0) { |
| CLOGE("[BD](%s[%d]): Plugin deinit failed!!", __FUNCTION__, __LINE__); |
| } |
| for(int i = 0; i < MAX_BD_BUFF_NUM; i++) { |
| if(m_BDbuffer[i].data != NULL){ |
| delete []m_BDbuffer[i].data; |
| } |
| } |
| } |
| m_BDstatus = BLUR_DETECTION_DEINIT; |
| #endif |
| |
| #ifdef USE_DVFS_LOCK |
| if (m_exynosCameraParameters->getDvfsLock() == true) |
| m_exynosCameraParameters->setDvfsLock(false); |
| #endif |
| break; |
| case 1573: /* HAL_CMD_DELETE_BURST_TAKE */ |
| CLOGD("DEBUG(%s):HAL_CMD_DELETE_BURST_TAKE is called!", __FUNCTION__); |
| m_takePictureCounter.setCount(0); |
| break; |
| #endif |
| #ifdef LLS_CAPTURE |
| case 1600: /* CAMERA_CMD_START_BURST_PANORAMA */ |
| CLOGD("DEBUG(%s):CAMERA_CMD_START_BURST_PANORAMA is called!", __FUNCTION__); |
| m_takePictureCounter.setCount(0); |
| break; |
| case 1601: /*CAMERA_CMD_STOP_BURST_PANORAMA */ |
| CLOGD("DEBUG(%s):CAMERA_CMD_STOP_BURST_PANORAMA is called!", __FUNCTION__); |
| m_takePictureCounter.setCount(0); |
| break; |
| case 1516: /*CAMERA_CMD_START_SERIES_CAPTURE */ |
| CLOGD("DEBUG(%s):CAMERA_CMD_START_SERIES_CAPTURE is called!%d", __FUNCTION__, arg1); |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| m_clearOneSecondBurst(false); |
| #endif |
| m_exynosCameraParameters->setSeriesShotMode(SERIES_SHOT_MODE_LLS, arg1); |
| m_takePictureCounter.setCount(0); |
| break; |
| case 1517: /* CAMERA_CMD_STOP_SERIES_CAPTURE */ |
| CLOGD("DEBUG(%s):CAMERA_CMD_STOP_SERIES_CAPTURE is called!", __FUNCTION__); |
| m_exynosCameraParameters->setSeriesShotMode(SERIES_SHOT_MODE_NONE); |
| m_takePictureCounter.setCount(0); |
| #ifdef SET_LLS_CAPTURE_SETFILE |
| m_exynosCameraParameters->setLLSCaptureOn(false); |
| #endif |
| #ifdef FLASHED_LLS_CAPTURE |
| if (getCameraId() == CAMERA_ID_BACK && m_captureSelector->getFlashedLLSCaptureStatus() == true) { |
| m_captureSelector->setFlashedLLSCaptureStatus(false); |
| #ifdef LLS_REPROCESSING |
| ExynosCameraActivitySpecialCapture *m_sCaptureMgr = m_exynosCameraActivityControl->getSpecialCaptureMgr(); |
| m_sCaptureMgr->setIsFlashLLSCapture(false); |
| #endif |
| } |
| #endif |
| |
| #ifdef OIS_CAPTURE |
| if (getCameraId() == CAMERA_ID_BACK && !m_exynosCameraParameters->getOISCaptureModeOn()) { |
| ExynosCameraActivitySpecialCapture *m_sCaptureMgr = m_exynosCameraActivityControl->getSpecialCaptureMgr(); |
| m_sCaptureMgr->setMultiCaptureMode(false); |
| } |
| #endif |
| break; |
| #endif |
| case 1351: /*CAMERA_CMD_AUTO_LOW_LIGHT_SET */ |
| CLOGD("DEBUG(%s):CAMERA_CMD_AUTO_LOW_LIGHT_SET is called!%d", __FUNCTION__, arg1); |
| if(arg1) { |
| if( m_flagLLSStart != true) { |
| m_flagLLSStart = true; |
| #ifdef LLS_CAPTURE |
| m_exynosCameraParameters->setLLSOn(m_flagLLSStart); |
| m_exynosCameraParameters->m_setLLSShotMode(); |
| #endif |
| } |
| } else { |
| m_flagLLSStart = false; |
| #ifdef LLS_CAPTURE |
| m_exynosCameraParameters->setLLSOn(m_flagLLSStart); |
| m_exynosCameraParameters->m_setShotMode(m_exynosCameraParameters->getShotMode()); |
| #endif |
| } |
| break; |
| case 1801: /* HAL_ENABLE_LIGHT_CONDITION*/ |
| CLOGD("DEBUG(%s):HAL_ENABLE_LIGHT_CONDITION is called!%d", __FUNCTION__, arg1); |
| if(arg1) { |
| m_flagLightCondition = true; |
| } else { |
| m_flagLightCondition = false; |
| } |
| break; |
| #ifdef SAMSUNG_CAMERA_EXTRA_INFO |
| case 1802: /* HAL_ENABLE_FLASH_AUTO_CALLBACK*/ |
| CLOGD("DEBUG(%s):HAL_ENABLE_FLASH_AUTO_CALLBACK is called!%d", __FUNCTION__, arg1); |
| if(arg1) { |
| m_flagFlashCallback = true; |
| } else { |
| m_flagFlashCallback = false; |
| } |
| break; |
| case 1803: /* HAL_ENABLE_HDR_AUTO_CALLBACK*/ |
| CLOGD("DEBUG(%s):HAL_ENABLE_HDR_AUTO_CALLBACK is called!%d", __FUNCTION__, arg1); |
| if(arg1) { |
| m_flagHdrCallback = true; |
| } else { |
| m_flagHdrCallback = false; |
| } |
| break; |
| #endif |
| #ifdef SR_CAPTURE |
| case 1519: /* CAMERA_CMD_SUPER_RESOLUTION_MODE */ |
| CLOGD("DEBUG(%s):CAMERA_CMD_SUPER_RESOLUTION_MODE is called!%d", __FUNCTION__, arg1); |
| m_exynosCameraParameters->setSROn(arg1); |
| if (arg1) { |
| m_sr_cropped_width = 0; |
| m_sr_cropped_height = 0; |
| m_isCopySrMdeta = true; |
| memset(m_faces_sr, 0, sizeof(camera_face_t) * NUM_OF_DETECTED_FACES); |
| memset(&m_sr_frameMetadata, 0, sizeof(camera_frame_metadata_t)); |
| } |
| break; |
| #endif |
| /* 1508: HAL_SET_SAMSUNG_CAMERA */ |
| case 1508 : |
| CLOGD("DEBUG(%s):HAL_SET_SAMSUNG_CAMERA is called!%d", __FUNCTION__, arg1); |
| m_exynosCameraParameters->setSamsungCamera(true); |
| break; |
| /* 1510: CAMERA_CMD_SET_FLIP */ |
| case 1510 : |
| CLOGD("DEBUG(%s):CAMERA_CMD_SET_FLIP is called!%d", __FUNCTION__, arg1); |
| m_exynosCameraParameters->setFlipHorizontal(arg1); |
| break; |
| /* 1521: CAMERA_CMD_DEVICE_ORIENTATION */ |
| case 1521: |
| CLOGD("DEBUG(%s):CAMERA_CMD_DEVICE_ORIENTATION is called!%d", __FUNCTION__, arg1); |
| m_exynosCameraParameters->setDeviceOrientation(arg1); |
| uctlMgr = m_exynosCameraActivityControl->getUCTLMgr(); |
| if (uctlMgr != NULL) |
| uctlMgr->setDeviceRotation(m_exynosCameraParameters->getFdOrientation()); |
| break; |
| /*1641: CAMERA_CMD_ADVANCED_MACRO_FOCUS*/ |
| case 1641: |
| CLOGD("DEBUG(%s):CAMERA_CMD_ADVANCED_MACRO_FOCUS is called!%d", __FUNCTION__, arg1); |
| m_exynosCameraParameters->setAutoFocusMacroPosition(ExynosCameraActivityAutofocus::AUTOFOCUS_MACRO_POSITION_CENTER); |
| break; |
| /*1642: CAMERA_CMD_FOCUS_LOCATION*/ |
| case 1642: |
| CLOGD("DEBUG(%s):CAMERA_CMD_FOCUS_LOCATION is called!%d", __FUNCTION__, arg1); |
| m_exynosCameraParameters->setAutoFocusMacroPosition(ExynosCameraActivityAutofocus::AUTOFOCUS_MACRO_POSITION_CENTER_UP); |
| break; |
| #ifdef SAMSUNG_DOF |
| /*1643: HAL_ENABLE_CURRENT_SET */ |
| case 1643: |
| CLOGD("DEBUG(%s):HAL_ENABLE_CURRENT_SET is called!%d", __FUNCTION__, arg1); |
| if(arg1) |
| startCurrentSet(); |
| else |
| stopCurrentSet(); |
| break; |
| /*1644: HAL_ENABLE_PAF_RESULT */ |
| case 1644: |
| CLOGD("DEBUG(%s):HAL_ENABLE_PAF_RESULT is called!%d", __FUNCTION__, arg1); |
| break; |
| /*1650: CAMERA_CMD_START_PAF_CALLBACK */ |
| case 1650: |
| CLOGD("DEBUG(%s):CAMERA_CMD_START_PAF_CALLBACK is called!%d", __FUNCTION__, arg1); |
| autoFocusMgr->setPDAF(true); |
| break; |
| /*1651: CAMERA_CMD_STOP_PAF_CALLBACK */ |
| case 1651: |
| CLOGD("DEBUG(%s):CAMERA_CMD_STOP_PAF_CALLBACK is called!%d", __FUNCTION__, arg1); |
| autoFocusMgr->setPDAF(false); |
| break; |
| #endif |
| /*1661: CAMERA_CMD_START_ZOOM */ |
| case 1661: |
| CLOGD("DEBUG(%s):CAMERA_CMD_START_ZOOM is called!", __FUNCTION__); |
| m_exynosCameraParameters->setZoomActiveOn(true); |
| m_exynosCameraParameters->setFocusModeLock(true); |
| break; |
| /*1662: CAMERA_CMD_STOP_ZOOM */ |
| case 1662: |
| CLOGD("DEBUG(%s):CAMERA_CMD_STOP_ZOOM is called!", __FUNCTION__); |
| m_exynosCameraParameters->setZoomActiveOn(false); |
| m_exynosCameraParameters->setFocusModeLock(false); |
| #ifdef SAMSUNG_OIS |
| m_exynosCameraParameters->setOISMode(); |
| #endif |
| break; |
| #ifdef SAMSUNG_HLV |
| case 1721: /* HAL_RECORDING_RESUME */ |
| { |
| UNI_PLUGIN_CAPTURE_STATUS value = UNI_PLUGIN_CAPTURE_STATUS_VID_REC_RESUME; |
| ALOGD("HLV: set UNI_PLUGIN_CAPTURE_STATUS_VID_REC_RESUME"); |
| |
| if (m_HLV) { |
| uni_plugin_set(m_HLV, |
| HIGHLIGHT_VIDEO_PLUGIN_NAME, |
| UNI_PLUGIN_INDEX_CAPTURE_STATUS, |
| &value); |
| } |
| else { |
| ALOGE("HLV: %s not yet loaded", HIGHLIGHT_VIDEO_PLUGIN_NAME); |
| } |
| } |
| break; |
| |
| case 1722: /* HAL_RECORDING_PAUSE */ |
| { |
| ALOGD("HLV: set UNI_PLUGIN_CAPTURE_STATUS_VID_REC_PAUSE"); |
| UNI_PLUGIN_CAPTURE_STATUS value = UNI_PLUGIN_CAPTURE_STATUS_VID_REC_PAUSE; |
| |
| if (m_HLV) { |
| uni_plugin_set(m_HLV, |
| HIGHLIGHT_VIDEO_PLUGIN_NAME, |
| UNI_PLUGIN_INDEX_CAPTURE_STATUS, |
| &value); |
| } |
| else { |
| ALOGE("HLV: %s not yet loaded", HIGHLIGHT_VIDEO_PLUGIN_NAME); |
| } |
| } |
| break; |
| #endif |
| |
| #ifdef USE_LIVE_BROADCAST |
| case 1730: /* SET PLB mode */ |
| CLOGD("DEBUG(%s):SET PLB mode is called!%d", __FUNCTION__, arg1); |
| m_exynosCameraParameters->setPLBMode((bool)arg1); |
| break; |
| #endif |
| |
| default: |
| CLOGV("DEBUG(%s):unexpectect command(%d)", __FUNCTION__, command); |
| break; |
| } |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::generateFrame(int32_t frameCount, ExynosCameraFrame **newFrame) |
| { |
| Mutex::Autolock lock(m_frameLock); |
| |
| int ret = 0; |
| *newFrame = NULL; |
| |
| if (frameCount >= 0) { |
| ret = m_searchFrameFromList(&m_processList, frameCount, newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):searchFrameFromList fail", __FUNCTION__, __LINE__); |
| return INVALID_OPERATION; |
| } |
| } |
| |
| if (*newFrame == NULL) { |
| *newFrame = m_previewFrameFactory->createNewFrame(); |
| |
| if (*newFrame == NULL) { |
| CLOGE("ERR(%s):newFrame is NULL", __FUNCTION__); |
| return UNKNOWN_ERROR; |
| } |
| |
| bool flagRequested = false; |
| |
| if (isOwnScc(getCameraId()) == true) |
| flagRequested = (*newFrame)->getRequest(PIPE_SCC); |
| else |
| flagRequested = (*newFrame)->getRequest(PIPE_ISPC); |
| |
| if (flagRequested == true) { |
| m_dynamicSccCount++; |
| CLOGV("DEBUG(%s[%d]):dynamicSccCount inc(%d) frameCount(%d)", __FUNCTION__, __LINE__, m_dynamicSccCount, (*newFrame)->getFrameCount()); |
| } |
| |
| m_processList.push_back(*newFrame); |
| } |
| |
| return ret; |
| } |
| |
| status_t ExynosCamera::generateFrameSccScp(uint32_t pipeId, uint32_t *frameCount, ExynosCameraFrame **frame) |
| { |
| int ret = 0; |
| int regenerateFrame = 0; |
| int count = *frameCount; |
| ExynosCameraFrame *newframe = NULL; |
| |
| do { |
| *frame = NULL; |
| ret = generateFrame(count, frame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):generateFrame fail, pipeID: %d", __FUNCTION__, __LINE__, pipeId); |
| return ret; |
| } |
| |
| newframe = *frame; |
| if (((PIPE_SCP == pipeId) && newframe->getScpDrop()) || |
| ((m_cameraId == CAMERA_ID_FRONT) && (PIPE_SCC == pipeId) && (newframe->getSccDrop() == true)) || |
| ((m_cameraId == CAMERA_ID_FRONT) && (PIPE_ISPC == pipeId) && (newframe->getIspcDrop() == true))) { |
| count++; |
| |
| ret = newframe->setEntityState(pipeId, ENTITY_STATE_FRAME_SKIP); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setEntityState fail, pipeId(%d), state(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId, ENTITY_STATE_FRAME_SKIP, ret); |
| *frameCount = count; |
| return ret; |
| } |
| |
| /* let m_mainThreadFunc handle the processlist cleaning part */ |
| m_pipeFrameDoneQ->pushProcessQ(&newframe); |
| |
| regenerateFrame = 1; |
| continue; |
| } |
| regenerateFrame = 0; |
| } while (regenerateFrame); |
| |
| *frameCount = count; |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_setupEntity( |
| uint32_t pipeId, |
| ExynosCameraFrame *newFrame, |
| ExynosCameraBuffer *srcBuf, |
| ExynosCameraBuffer *dstBuf) |
| { |
| int ret = 0; |
| entity_buffer_state_t entityBufferState; |
| |
| /* set SRC buffer */ |
| ret = newFrame->getSrcBufferState(pipeId, &entityBufferState); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getSrcBufferState fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId, ret); |
| return ret; |
| } |
| |
| if (entityBufferState == ENTITY_BUFFER_STATE_REQUESTED) { |
| ret = m_setSrcBuffer(pipeId, newFrame, srcBuf); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_setSrcBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId, ret); |
| return ret; |
| } |
| } |
| |
| /* set DST buffer */ |
| ret = newFrame->getDstBufferState(pipeId, &entityBufferState); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBufferState fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId, ret); |
| return ret; |
| } |
| |
| if (entityBufferState == ENTITY_BUFFER_STATE_REQUESTED) { |
| ret = m_setDstBuffer(pipeId, newFrame, dstBuf); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_setDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId, ret); |
| return ret; |
| } |
| } |
| |
| ret = newFrame->setEntityState(pipeId, ENTITY_STATE_PROCESSING); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setEntityState(ENTITY_STATE_PROCESSING) fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId, ret); |
| return ret; |
| } |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_setSrcBuffer( |
| uint32_t pipeId, |
| ExynosCameraFrame *newFrame, |
| ExynosCameraBuffer *buffer) |
| { |
| int ret = 0; |
| int bufIndex = -1; |
| ExynosCameraBufferManager *bufferMgr = NULL; |
| ExynosCameraBuffer srcBuf; |
| |
| if (buffer == NULL) { |
| buffer = &srcBuf; |
| |
| ret = m_getBufferManager(pipeId, &bufferMgr, SRC_BUFFER_DIRECTION); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getBufferManager(SRC) fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId, ret); |
| return ret; |
| } |
| |
| if (bufferMgr == NULL) { |
| CLOGE("ERR(%s[%d]):buffer manager is NULL, pipeId(%d)", __FUNCTION__, __LINE__, pipeId); |
| return BAD_VALUE; |
| } |
| |
| /* get buffers */ |
| ret = bufferMgr->getBuffer(&bufIndex, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL, buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getBuffer fail, pipeId(%d), frameCount(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId, newFrame->getFrameCount(), ret); |
| bufferMgr->dump(); |
| return ret; |
| } |
| } |
| |
| /* set buffers */ |
| ret = newFrame->setSrcBuffer(pipeId, *buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setSrcBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId, ret); |
| return ret; |
| } |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_setDstBuffer( |
| uint32_t pipeId, |
| ExynosCameraFrame *newFrame, |
| ExynosCameraBuffer *buffer) |
| { |
| int ret = 0; |
| int bufIndex = -1; |
| ExynosCameraBufferManager *bufferMgr = NULL; |
| ExynosCameraBuffer dstBuf; |
| |
| if (buffer == NULL) { |
| buffer = &dstBuf; |
| |
| ret = m_getBufferManager(pipeId, &bufferMgr, DST_BUFFER_DIRECTION); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getBufferManager(DST) fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId, ret); |
| return ret; |
| } |
| |
| if (bufferMgr == NULL) { |
| CLOGE("ERR(%s[%d]):buffer manager is NULL, pipeId(%d)", __FUNCTION__, __LINE__, pipeId); |
| return BAD_VALUE; |
| } |
| |
| /* get buffers */ |
| ret = bufferMgr->getBuffer(&bufIndex, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL, buffer); |
| if (ret < 0) { |
| ExynosCameraFrameEntity *curEntity = newFrame->searchEntityByPipeId(pipeId); |
| if (curEntity != NULL) { |
| if (curEntity->getBufType() == ENTITY_BUFFER_DELIVERY) { |
| CLOGV("DEBUG(%s[%d]): pipe(%d) buffer is empty for delivery", __FUNCTION__, __LINE__, pipeId); |
| buffer->index = -1; |
| } else { |
| CLOGE("ERR(%s[%d]):getBuffer fail, pipeId(%d), frameCount(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId, newFrame->getFrameCount(), ret); |
| return ret; |
| } |
| } else { |
| CLOGE("ERR(%s[%d]):curEntity is NULL, pipeId(%d)", __FUNCTION__, __LINE__, pipeId); |
| return ret; |
| } |
| } |
| } |
| |
| /* set buffers */ |
| ret = newFrame->setDstBuffer(pipeId, *buffer); |
| |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId, ret); |
| return ret; |
| } |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::generateFrameReprocessing(ExynosCameraFrame **newFrame) |
| { |
| Mutex::Autolock lock(m_frameLock); |
| |
| int ret = 0; |
| struct ExynosCameraBuffer tempBuffer; |
| int bufIndex = -1; |
| |
| /* 1. Make Frame */ |
| *newFrame = m_reprocessingFrameFactory->createNewFrame(); |
| if (*newFrame == NULL) { |
| CLOGE("ERR(%s):newFrame is NULL", __FUNCTION__); |
| return UNKNOWN_ERROR; |
| } |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_fastenAeStable(void) |
| { |
| int ret = 0; |
| ExynosCameraBuffer fastenAeBuffer[NUM_FASTAESTABLE_BUFFER]; |
| ExynosCameraBufferManager *skipBufferMgr = NULL; |
| m_createInternalBufferManager(&skipBufferMgr, "SKIP_BUF"); |
| |
| unsigned int planeSize[EXYNOS_CAMERA_BUFFER_MAX_PLANES] = {0}; |
| unsigned int bytesPerLine[EXYNOS_CAMERA_BUFFER_MAX_PLANES] = {0}; |
| planeSize[0] = 32 * 64 * 2; |
| int planeCount = 2; |
| #ifdef SAMSUNG_COMPANION |
| int bufferCount = (m_exynosCameraParameters->getRTHdr() == COMPANION_WDR_ON) ? |
| NUM_FASTAESTABLE_BUFFER : NUM_FASTAESTABLE_BUFFER - 4; |
| #else |
| int bufferCount = NUM_FASTAESTABLE_BUFFER; |
| #endif |
| |
| if (skipBufferMgr == NULL) { |
| CLOGE("ERR(%s[%d]):createBufferManager failed", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| ret = m_allocBuffers(skipBufferMgr, planeCount, planeSize, bytesPerLine, bufferCount, true, false); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_3aaBufferMgr m_allocBuffers(bufferCount=%d) fail", |
| __FUNCTION__, __LINE__, bufferCount); |
| return ret; |
| } |
| |
| for (int i = 0; i < bufferCount; i++) { |
| int index = i; |
| ret = skipBufferMgr->getBuffer(&index, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL, &fastenAeBuffer[i]); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getBuffer fail", __FUNCTION__, __LINE__); |
| goto done; |
| } |
| } |
| |
| ret = m_previewFrameFactory->fastenAeStable(bufferCount, fastenAeBuffer); |
| if (ret < 0) { |
| ret = INVALID_OPERATION; |
| // doing some error handling |
| } |
| |
| m_checkFirstFrameLux = true; |
| done: |
| skipBufferMgr->deinit(); |
| delete skipBufferMgr; |
| skipBufferMgr = NULL; |
| |
| func_exit: |
| return ret; |
| } |
| |
| #ifdef CAMERA_FAST_ENTRANCE_V1 |
| bool ExynosCamera::m_fastenAeThreadFunc(void) |
| { |
| CLOGI("INFO(%s[%d]):", __FUNCTION__, __LINE__); |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| |
| int32_t skipFrameCount = INITIAL_SKIP_FRAME; |
| int ret = NO_ERROR; |
| m_fastenAeThreadResult = 0; |
| |
| /* frame manager start */ |
| m_frameMgr->start(); |
| |
| /* |
| * This is for updating parameter value at once. |
| * This must be just before making factory |
| */ |
| m_exynosCameraParameters->updateTpuParameters(); |
| |
| /* setup frameFactory with scenario */ |
| m_setupFrameFactory(); |
| |
| if (m_previewFrameFactory->isCreated() == false) { |
| #if defined(SAMSUNG_EEPROM) |
| if ((m_use_companion == false) && (isEEprom(getCameraId()) == true)) { |
| if (m_eepromThread != NULL) { |
| CLOGD("DEBUG(%s): eepromThread join.....", __FUNCTION__); |
| m_eepromThread->join(); |
| } else { |
| CLOGD("DEBUG(%s): eepromThread is NULL.", __FUNCTION__); |
| } |
| m_exynosCameraParameters->setRomReadThreadDone(true); |
| CLOGD("DEBUG(%s): eepromThread joined", __FUNCTION__); |
| } |
| #endif /* SAMSUNG_EEPROM */ |
| |
| #ifdef SAMSUNG_COMPANION |
| if(m_use_companion == true) { |
| ret = m_previewFrameFactory->precreate(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_previewFrameFactory->precreate() failed", __FUNCTION__, __LINE__); |
| goto err; |
| } |
| |
| m_waitCompanionThreadEnd(); |
| |
| m_exynosCameraParameters->setRomReadThreadDone(true); |
| |
| ret = m_previewFrameFactory->postcreate(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_previewFrameFactory->postcreate() failed", __FUNCTION__, __LINE__); |
| goto err; |
| } |
| } else { |
| ret = m_previewFrameFactory->create(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_previewFrameFactory->create() failed", __FUNCTION__, __LINE__); |
| goto err; |
| } |
| } |
| #else |
| ret = m_previewFrameFactory->create(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_previewFrameFactory->create() failed", __FUNCTION__, __LINE__); |
| goto err; |
| } |
| #endif /* SAMSUNG_COMPANION */ |
| CLOGD("DEBUG(%s):FrameFactory(previewFrameFactory) created", __FUNCTION__); |
| } |
| |
| #ifdef USE_QOS_SETTING |
| ret = m_previewFrameFactory->setControl(V4L2_CID_IS_DVFS_CLUSTER1, BIG_CORE_MAX_LOCK, PIPE_3AA); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):V4L2_CID_IS_DVFS_CLUSTER1 setControl fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| #endif |
| |
| if (m_exynosCameraParameters->getUseFastenAeStable() == true && |
| m_exynosCameraParameters->getDualMode() == false && |
| m_exynosCameraParameters->getRecordingHint() == false && |
| m_isFirstStart == true) { |
| |
| ret = m_fastenAeStable(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_fastenAeStable() failed", __FUNCTION__, __LINE__); |
| goto err; |
| } else { |
| skipFrameCount = 0; |
| m_exynosCameraParameters->setUseFastenAeStable(false); |
| } |
| } |
| |
| #ifdef USE_FADE_IN_ENTRANCE |
| if (m_exynosCameraParameters->getUseFastenAeStable() == true) { |
| CLOGE("ERR(%s[%d]):consistency in skipFrameCount might be broken by FASTEN_AE and FADE_IN", __FUNCTION__, __LINE__); |
| } |
| #endif |
| |
| m_exynosCameraParameters->setFrameSkipCount(skipFrameCount); |
| |
| /* one shot */ |
| return false; |
| |
| err: |
| m_fastenAeThreadResult = ret; |
| |
| #ifdef SAMSUNG_COMPANION |
| if(m_use_companion == true) { |
| m_waitCompanionThreadEnd(); |
| } |
| #endif |
| #if defined(SAMSUNG_EEPROM) |
| if ((m_use_companion == false) && (isEEprom(getCameraId()) == true)) { |
| if (m_eepromThread != NULL) { |
| m_eepromThread->join(); |
| } else { |
| CLOGD("DEBUG(%s): eepromThread is NULL.", __FUNCTION__); |
| } |
| } |
| #endif |
| |
| return false; |
| } |
| |
| status_t ExynosCamera::m_waitFastenAeThreadEnd(void) |
| { |
| ExynosCameraDurationTimer timer; |
| |
| timer.start(); |
| |
| if(m_fastEntrance == true) { |
| if (m_fastenAeThread != NULL) { |
| m_fastenAeThread->join(); |
| } else { |
| CLOGI("INFO(%s[%d]):m_fastenAeThread is NULL", __FUNCTION__, __LINE__); |
| } |
| } |
| |
| timer.stop(); |
| |
| CLOGD("DEBUG(%s[%d]):fastenAeThread waiting time : duration time(%5d msec)", __FUNCTION__, __LINE__, (int)timer.durationMsecs()); |
| CLOGD("DEBUG(%s[%d]):fastenAeThread join", __FUNCTION__, __LINE__); |
| |
| return NO_ERROR; |
| } |
| #endif |
| |
| status_t ExynosCamera::m_startPreviewInternal(void) |
| { |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| |
| CLOGI("DEBUG(%s[%d]):IN", __FUNCTION__, __LINE__); |
| |
| uint32_t minBayerFrameNum = 0; |
| uint32_t min3AAFrameNum = 0; |
| int ret = 0; |
| ExynosCameraFrame *newFrame = NULL; |
| ExynosCameraBuffer dstBuf; |
| ExynosCameraBufferManager *scpBufferMgr = NULL; |
| int32_t reprocessingBayerMode = m_exynosCameraParameters->getReprocessingBayerMode(); |
| enum pipeline pipe; |
| bool zoomWithScaler = false; |
| |
| m_fliteFrameCount = 0; |
| m_3aa_ispFrameCount = 0; |
| m_ispFrameCount = 0; |
| m_sccFrameCount = 0; |
| m_scpFrameCount = 0; |
| m_displayPreviewToggle = 0; |
| |
| zoomWithScaler = m_exynosCameraParameters->getSupportedZoomPreviewWIthScaler(); |
| |
| if (m_exynosCameraParameters->isFlite3aaOtf() == true) |
| minBayerFrameNum = m_exynosconfig->current->bufInfo.init_bayer_buffers; |
| else |
| minBayerFrameNum = m_exynosconfig->current->bufInfo.num_bayer_buffers |
| - m_exynosconfig->current->bufInfo.reprocessing_bayer_hold_count; |
| |
| /* |
| * with MCPipe, we need to putBuffer 3 buf. |
| */ |
| /* |
| if (reprocessingBayerMode == REPROCESSING_BAYER_MODE_DIRTY_ALWAYS_ON) |
| min3AAFrameNum = minBayerFrameNum; |
| else |
| min3AAFrameNum = m_exynosconfig->current->pipeInfo.prepare[PIPE_3AA]; |
| */ |
| |
| min3AAFrameNum = m_exynosconfig->current->pipeInfo.prepare[PIPE_3AA]; |
| |
| ExynosCameraBufferManager *taaBufferManager[MAX_NODE]; |
| ExynosCameraBufferManager *ispBufferManager[MAX_NODE]; |
| ExynosCameraBufferManager *disBufferManager[MAX_NODE]; |
| |
| for (int i = 0; i < MAX_NODE; i++) { |
| taaBufferManager[i] = NULL; |
| ispBufferManager[i] = NULL; |
| disBufferManager[i] = NULL; |
| } |
| |
| m_exynosCameraParameters->setZoomPreviewWIthScaler(zoomWithScaler); |
| |
| #ifdef FPS_CHECK |
| for (int i = 0; i < DEBUG_MAX_PIPE_NUM; i++) |
| m_debugFpsCount[i] = 0; |
| #endif |
| |
| switch (reprocessingBayerMode) { |
| case REPROCESSING_BAYER_MODE_NONE : /* Not using reprocessing */ |
| CLOGD("DEBUG(%s[%d]): Use REPROCESSING_BAYER_MODE_NONE", __FUNCTION__, __LINE__); |
| m_previewFrameFactory->setRequestFLITE(false); |
| m_previewFrameFactory->setRequest3AC(false); |
| break; |
| case REPROCESSING_BAYER_MODE_PURE_ALWAYS_ON : |
| CLOGD("DEBUG(%s[%d]): Use REPROCESSING_BAYER_MODE_PURE_ALWAYS_ON", __FUNCTION__, __LINE__); |
| m_previewFrameFactory->setRequestFLITE(true); |
| m_previewFrameFactory->setRequest3AC(false); |
| break; |
| case REPROCESSING_BAYER_MODE_DIRTY_ALWAYS_ON : |
| CLOGD("DEBUG(%s[%d]): Use REPROCESSING_BAYER_MODE_DIRTY_ALWAYS_ON", __FUNCTION__, __LINE__); |
| m_previewFrameFactory->setRequestFLITE(false); |
| m_previewFrameFactory->setRequest3AC(true); |
| break; |
| case REPROCESSING_BAYER_MODE_PURE_DYNAMIC : |
| CLOGD("DEBUG(%s[%d]): Use REPROCESSING_BAYER_MODE_PURE_DYNAMIC", __FUNCTION__, __LINE__); |
| m_previewFrameFactory->setRequestFLITE(false); |
| m_previewFrameFactory->setRequest3AC(false); |
| break; |
| case REPROCESSING_BAYER_MODE_DIRTY_DYNAMIC : |
| CLOGD("DEBUG(%s[%d]): Use REPROCESSING_BAYER_MODE_DIRTY_DYNAMIC", __FUNCTION__, __LINE__); |
| m_previewFrameFactory->setRequestFLITE(false); |
| m_previewFrameFactory->setRequest3AC(false); |
| break; |
| default : |
| CLOGE("ERR(%s[%d]): Unknown dynamic bayer mode", __FUNCTION__, __LINE__); |
| m_previewFrameFactory->setRequest3AC(false); |
| break; |
| } |
| |
| if (m_exynosCameraParameters->getZoomPreviewWIthScaler() == true) { |
| scpBufferMgr = m_zoomScalerBufferMgr; |
| } else { |
| scpBufferMgr = m_scpBufferMgr; |
| } |
| |
| if (m_exynosCameraParameters->getTpuEnabledMode() == true) { |
| m_previewFrameFactory->setRequestISPP(true); |
| m_previewFrameFactory->setRequestDIS(true); |
| |
| if (m_exynosCameraParameters->is3aaIspOtf() == true) { |
| taaBufferManager[m_previewFrameFactory->getNodeType(PIPE_3AA)] = m_3aaBufferMgr; |
| taaBufferManager[m_previewFrameFactory->getNodeType(PIPE_3AC)] = m_bayerBufferMgr; |
| taaBufferManager[m_previewFrameFactory->getNodeType(PIPE_ISPP)] = m_hwDisBufferMgr; |
| |
| disBufferManager[m_previewFrameFactory->getNodeType(PIPE_DIS)] = m_hwDisBufferMgr; |
| disBufferManager[m_previewFrameFactory->getNodeType(PIPE_SCP)] = scpBufferMgr; |
| } else { |
| taaBufferManager[m_previewFrameFactory->getNodeType(PIPE_3AA)] = m_3aaBufferMgr; |
| taaBufferManager[m_previewFrameFactory->getNodeType(PIPE_3AC)] = m_bayerBufferMgr; |
| taaBufferManager[m_previewFrameFactory->getNodeType(PIPE_3AP)] = m_ispBufferMgr; |
| |
| ispBufferManager[m_previewFrameFactory->getNodeType(PIPE_ISP)] = m_ispBufferMgr; |
| ispBufferManager[m_previewFrameFactory->getNodeType(PIPE_ISPP)] = m_hwDisBufferMgr; |
| |
| disBufferManager[m_previewFrameFactory->getNodeType(PIPE_DIS)] = m_hwDisBufferMgr; |
| disBufferManager[m_previewFrameFactory->getNodeType(PIPE_SCP)] = scpBufferMgr; |
| } |
| } else { |
| m_previewFrameFactory->setRequestISPP(false); |
| m_previewFrameFactory->setRequestDIS(false); |
| |
| if (m_exynosCameraParameters->is3aaIspOtf() == true) { |
| if (m_exynosCameraParameters->getDualMode() == true && getCameraId() == CAMERA_ID_FRONT) { |
| m_previewFrameFactory->setRequestFLITE(true); |
| m_previewFrameFactory->setRequestISPC(true); |
| |
| taaBufferManager[m_previewFrameFactory->getNodeType(PIPE_3AA)] = m_bayerBufferMgr; |
| taaBufferManager[m_previewFrameFactory->getNodeType(PIPE_ISPC)] = m_sccBufferMgr; |
| } else { |
| taaBufferManager[m_previewFrameFactory->getNodeType(PIPE_3AA)] = m_3aaBufferMgr; |
| #ifndef RAWDUMP_CAPTURE |
| taaBufferManager[m_previewFrameFactory->getNodeType(PIPE_3AC)] = m_bayerBufferMgr; |
| #endif |
| taaBufferManager[m_previewFrameFactory->getNodeType(PIPE_SCP)] = scpBufferMgr; |
| } |
| } else { |
| taaBufferManager[m_previewFrameFactory->getNodeType(PIPE_3AA)] = m_3aaBufferMgr; |
| taaBufferManager[m_previewFrameFactory->getNodeType(PIPE_3AC)] = m_bayerBufferMgr; |
| taaBufferManager[m_previewFrameFactory->getNodeType(PIPE_3AP)] = m_ispBufferMgr; |
| |
| ispBufferManager[m_previewFrameFactory->getNodeType(PIPE_ISP)] = m_ispBufferMgr; |
| ispBufferManager[m_previewFrameFactory->getNodeType(PIPE_SCP)] = scpBufferMgr; |
| } |
| } |
| |
| for (int i = 0; i < MAX_NODE; i++) { |
| /* If even one buffer slot is valid. call setBufferManagerToPipe() */ |
| if (taaBufferManager[i] != NULL) { |
| ret = m_previewFrameFactory->setBufferManagerToPipe(taaBufferManager, PIPE_3AA); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):m_previewFrameFactory->setBufferManagerToPipe(taaBufferManager, %d) failed", |
| __FUNCTION__, __LINE__, PIPE_3AA); |
| return ret; |
| } |
| break; |
| } |
| } |
| |
| for (int i = 0; i < MAX_NODE; i++) { |
| /* If even one buffer slot is valid. call setBufferManagerToPipe() */ |
| if (ispBufferManager[i] != NULL) { |
| ret = m_previewFrameFactory->setBufferManagerToPipe(ispBufferManager, PIPE_ISP); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):m_previewFrameFactory->setBufferManagerToPipe(ispBufferManager, %d) failed", |
| __FUNCTION__, __LINE__, PIPE_ISP); |
| return ret; |
| } |
| break; |
| } |
| } |
| |
| for (int i = 0; i < MAX_NODE; i++) { |
| /* If even one buffer slot is valid. call setBufferManagerToPipe() */ |
| if (disBufferManager[i] != NULL) { |
| ret = m_previewFrameFactory->setBufferManagerToPipe(disBufferManager, PIPE_DIS); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):m_previewFrameFactory->setBufferManagerToPipe(disBufferManager, %d) failed", |
| __FUNCTION__, __LINE__, PIPE_DIS); |
| return ret; |
| } |
| break; |
| } |
| } |
| |
| ret = m_previewFrameFactory->initPipes(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_previewFrameFactory->initPipes() failed", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| m_printExynosCameraInfo(__FUNCTION__); |
| |
| for (uint32_t i = 0; i < minBayerFrameNum; i++) { |
| ret = generateFrame(i, &newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):generateFrame fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| if (newFrame == NULL) { |
| CLOGE("ERR(%s[%d]):new faame is NULL", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| m_fliteFrameCount++; |
| |
| if (m_exynosCameraParameters->isFlite3aaOtf() == true) { |
| if (reprocessingBayerMode == REPROCESSING_BAYER_MODE_PURE_ALWAYS_ON) { |
| m_setupEntity(m_getBayerPipeId(), newFrame); |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, m_getBayerPipeId()); |
| m_previewFrameFactory->pushFrameToPipe(&newFrame, m_getBayerPipeId()); |
| } |
| |
| if (i < min3AAFrameNum) { |
| m_setupEntity(PIPE_3AA, newFrame); |
| |
| if (m_exynosCameraParameters->is3aaIspOtf() == true) { |
| m_previewFrameFactory->setFrameDoneQToPipe(m_pipeFrameDoneQ, PIPE_3AA); |
| |
| if (m_exynosCameraParameters->getTpuEnabledMode() == true) { |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, PIPE_DIS); |
| } |
| } else { |
| m_previewFrameFactory->setFrameDoneQToPipe(m_pipeFrameDoneQ, PIPE_3AA); |
| |
| if (m_exynosCameraParameters->getTpuEnabledMode() == true) { |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, PIPE_DIS); |
| m_previewFrameFactory->setFrameDoneQToPipe(m_pipeFrameDoneQ, PIPE_ISP); |
| } else { |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, PIPE_ISP); |
| } |
| } |
| |
| m_previewFrameFactory->pushFrameToPipe(&newFrame, PIPE_3AA); |
| m_3aa_ispFrameCount++; |
| } |
| } else { |
| m_setupEntity(m_getBayerPipeId(), newFrame); |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, m_getBayerPipeId()); |
| m_previewFrameFactory->pushFrameToPipe(&newFrame, m_getBayerPipeId()); |
| |
| if (m_exynosCameraParameters->is3aaIspOtf() == true) { |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, PIPE_3AA); |
| } else { |
| m_setupEntity(PIPE_3AA, newFrame); |
| m_previewFrameFactory->setFrameDoneQToPipe(m_pipeFrameDoneQ, PIPE_3AA); |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, PIPE_ISP); |
| m_previewFrameFactory->pushFrameToPipe(&newFrame, PIPE_3AA); |
| m_3aa_ispFrameCount++; |
| } |
| |
| } |
| #if 0 |
| /* SCC */ |
| if(m_exynosCameraParameters->isSccCapture() == true) { |
| m_sccFrameCount++; |
| |
| if (isOwnScc(getCameraId()) == true) { |
| pipe = PIPE_SCC; |
| } else { |
| pipe = PIPE_ISPC; |
| } |
| |
| if(newFrame->getRequest(pipe)) { |
| m_setupEntity(pipe, newFrame); |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, pipe); |
| m_previewFrameFactory->pushFrameToPipe(&newFrame, pipe); |
| } |
| } |
| #endif |
| /* SCP */ |
| /* Comment out, because it included ISP */ |
| /* |
| m_scpFrameCount++; |
| |
| m_setupEntity(PIPE_SCP, newFrame); |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, PIPE_SCP); |
| m_previewFrameFactory->pushFrameToPipe(&newFrame, PIPE_SCP); |
| */ |
| } |
| |
| /* Comment out, because it included ISP */ |
| /* |
| for (uint32_t i = minFrameNum; i < INIT_SCP_BUFFERS; i++) { |
| ret = generateFrame(i, &newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):generateFrame fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| if (newFrame == NULL) { |
| CLOGE("ERR(%s[%d]):new faame is NULL", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| m_scpFrameCount++; |
| |
| m_setupEntity(PIPE_SCP, newFrame); |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, PIPE_SCP); |
| m_previewFrameFactory->pushFrameToPipe(&newFrame, PIPE_SCP); |
| } |
| */ |
| |
| /* prepare pipes */ |
| ret = m_previewFrameFactory->preparePipes(); |
| if (ret < 0) { |
| CLOGE("ERR(%s):preparePipe fail", __FUNCTION__); |
| return ret; |
| } |
| |
| #ifndef START_PICTURE_THREAD |
| if (m_exynosCameraParameters->isReprocessing() == true) { |
| m_startPictureInternal(); |
| } |
| #endif |
| |
| #ifdef RAWDUMP_CAPTURE |
| /* s_ctrl HAL version for selecting dvfs table */ |
| ret = m_previewFrameFactory->setControl(V4L2_CID_IS_HAL_VERSION, IS_HAL_VER_3_2, PIPE_3AA); |
| ALOGD("WARN(%s): V4L2_CID_IS_HAL_VERSION_%d pipe(%d)", __FUNCTION__, IS_HAL_VER_3_2, PIPE_3AA); |
| if (ret < 0) |
| ALOGW("WARN(%s): V4L2_CID_IS_HAL_VERSION is fail", __FUNCTION__); |
| #endif |
| |
| /* stream on pipes */ |
| ret = m_previewFrameFactory->startPipes(); |
| if (ret < 0) { |
| m_previewFrameFactory->stopPipes(); |
| CLOGE("ERR(%s):startPipe fail", __FUNCTION__); |
| return ret; |
| } |
| |
| /* start all thread */ |
| ret = m_previewFrameFactory->startInitialThreads(); |
| if (ret < 0) { |
| CLOGE("ERR(%s):startInitialThreads fail", __FUNCTION__); |
| return ret; |
| } |
| |
| m_previewEnabled = true; |
| m_exynosCameraParameters->setPreviewRunning(m_previewEnabled); |
| |
| if (m_exynosCameraParameters->getFocusModeSetting() == true) { |
| CLOGD("set Focus Mode(%s[%d])", __FUNCTION__, __LINE__); |
| int focusmode = m_exynosCameraParameters->getFocusMode(); |
| m_exynosCameraActivityControl->setAutoFocusMode(focusmode); |
| m_exynosCameraParameters->setFocusModeSetting(false); |
| } |
| |
| #ifdef SAMSUNG_OIS |
| if (m_exynosCameraParameters->getOISModeSetting() == true) { |
| CLOGD("set OIS Mode(%s[%d])", __FUNCTION__, __LINE__); |
| m_exynosCameraParameters->setOISMode(); |
| m_exynosCameraParameters->setOISModeSetting(false); |
| } |
| #endif |
| |
| CLOGI("DEBUG(%s[%d]):OUT", __FUNCTION__, __LINE__); |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_stopPreviewInternal(void) |
| { |
| int ret = 0; |
| |
| CLOGI("DEBUG(%s[%d]):IN", __FUNCTION__, __LINE__); |
| |
| if (m_previewFrameFactory != NULL) { |
| ret = m_previewFrameFactory->stopPipes(); |
| if (ret < 0) { |
| CLOGE("ERR(%s):stopPipe fail", __FUNCTION__); |
| return ret; |
| } |
| } |
| |
| CLOGD("DEBUG(%s[%d]):clear process Frame list", __FUNCTION__, __LINE__); |
| ret = m_clearList(&m_processList); |
| if (ret < 0) { |
| CLOGE("ERR(%s):m_clearList fail", __FUNCTION__); |
| return ret; |
| } |
| |
| /* clear previous recording frame */ |
| CLOGD("DEBUG(%s[%d]):Recording m_recordingProcessList(%d) IN", |
| __FUNCTION__, __LINE__, (int)m_recordingProcessList.size()); |
| m_recordingListLock.lock(); |
| ret = m_clearList(&m_recordingProcessList); |
| if (ret < 0) { |
| CLOGE("ERR(%s):m_clearList fail", __FUNCTION__); |
| } |
| m_recordingListLock.unlock(); |
| CLOGD("DEBUG(%s[%d]):Recording m_recordingProcessList(%d) OUT", |
| __FUNCTION__, __LINE__, (int)m_recordingProcessList.size()); |
| |
| m_pipeFrameDoneQ->release(); |
| |
| m_fliteFrameCount = 0; |
| m_3aa_ispFrameCount = 0; |
| m_ispFrameCount = 0; |
| m_sccFrameCount = 0; |
| m_scpFrameCount = 0; |
| m_isZSLCaptureOn = false; |
| |
| m_previewEnabled = false; |
| m_exynosCameraParameters->setPreviewRunning(m_previewEnabled); |
| |
| CLOGI("DEBUG(%s[%d]):OUT", __FUNCTION__, __LINE__); |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_startPictureInternal(void) |
| { |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| |
| int ret = 0; |
| unsigned int bytesPerLine[EXYNOS_CAMERA_BUFFER_MAX_PLANES] = {0}; |
| unsigned int planeSize[EXYNOS_CAMERA_BUFFER_MAX_PLANES] = {0}; |
| int hwPictureW, hwPictureH; |
| int planeCount = 1; |
| int minBufferCount = 1; |
| int maxBufferCount = 1; |
| exynos_camera_buffer_type_t type = EXYNOS_CAMERA_BUFFER_ION_CACHED_TYPE; |
| buffer_manager_allocation_mode_t allocMode = BUFFER_MANAGER_ALLOCATION_ONDEMAND; |
| ExynosCameraBufferManager *taaBufferManager[MAX_NODE]; |
| ExynosCameraBufferManager *ispBufferManager[MAX_NODE]; |
| for (int i = 0; i < MAX_NODE; i++) { |
| taaBufferManager[i] = NULL; |
| ispBufferManager[i] = NULL; |
| } |
| |
| if (m_zslPictureEnabled == true) { |
| CLOGD("DEBUG(%s[%d]): zsl picture is already initialized", __FUNCTION__, __LINE__); |
| return NO_ERROR; |
| } |
| |
| if (m_exynosCameraParameters->isReprocessing() == true) { |
| if( m_exynosCameraParameters->getHighSpeedRecording() ) { |
| m_exynosCameraParameters->getHwSensorSize(&hwPictureW, &hwPictureH); |
| CLOGI("(%s):HW Picture(HighSpeed) width x height = %dx%d", __FUNCTION__, hwPictureW, hwPictureH); |
| } else { |
| m_exynosCameraParameters->getMaxPictureSize(&hwPictureW, &hwPictureH); |
| CLOGI("(%s):HW Picture width x height = %dx%d", __FUNCTION__, hwPictureW, hwPictureH); |
| } |
| |
| if (SCC_OUTPUT_COLOR_FMT == V4L2_PIX_FMT_NV21M) { |
| planeSize[0] = ALIGN_UP(hwPictureW, GSCALER_IMG_ALIGN) * ALIGN_UP(hwPictureH, GSCALER_IMG_ALIGN); |
| planeSize[1] = ALIGN_UP(hwPictureW, GSCALER_IMG_ALIGN) * ALIGN_UP(hwPictureH, GSCALER_IMG_ALIGN) / 2; |
| planeCount = 3; |
| } else if (SCC_OUTPUT_COLOR_FMT == V4L2_PIX_FMT_NV21) { |
| planeSize[0] = ALIGN_UP(hwPictureW, GSCALER_IMG_ALIGN) * ALIGN_UP(hwPictureH, GSCALER_IMG_ALIGN) * 3 / 2; |
| planeCount = 2; |
| } else { |
| planeSize[0] = ALIGN_UP(hwPictureW, GSCALER_IMG_ALIGN) * ALIGN_UP(hwPictureH, GSCALER_IMG_ALIGN) * 2; |
| planeCount = 2; |
| } |
| minBufferCount = 1; |
| maxBufferCount = NUM_PICTURE_BUFFERS; |
| |
| if (m_exynosCameraParameters->getHighResolutionCallbackMode() == true) { |
| /* SCC Reprocessing Buffer realloc for high resolution callback */ |
| minBufferCount = 2; |
| } |
| |
| ret = m_allocBuffers(m_sccReprocessingBufferMgr, planeCount, planeSize, bytesPerLine, minBufferCount, maxBufferCount, type, allocMode, true, false); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_sccReprocessingBufferMgr m_allocBuffers(minBufferCount=%d, maxBufferCount=%d) fail", |
| __FUNCTION__, __LINE__, minBufferCount, maxBufferCount); |
| return ret; |
| } |
| |
| if (m_exynosCameraParameters->getUsePureBayerReprocessing() == true) { |
| ret = m_setReprocessingBuffer(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_setReprocessing Buffer fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| } |
| } |
| |
| if (m_reprocessingFrameFactory->isCreated() == false) { |
| ret = m_reprocessingFrameFactory->create(); |
| if (ret < 0) { |
| CLOGE("ERR(%s):m_reprocessingFrameFactory->create() failed", __FUNCTION__); |
| return ret; |
| } |
| |
| m_pictureFrameFactory = m_reprocessingFrameFactory; |
| CLOGD("DEBUG(%s[%d]):FrameFactory(pictureFrameFactory) created", __FUNCTION__, __LINE__); |
| } |
| |
| /* If we want set buffer namanger from m_getBufferManager, use this */ |
| #if 0 |
| ret = m_getBufferManager(PIPE_3AA_REPROCESSING, bufferManager[m_reprocessingFrameFactory->getNodeType(PIPE_3AA_REPROCESSING)], SRC_BUFFER_DIRECTION); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getBufferManager() fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, PIPE_3AA_REPROCESSING, ret); |
| return ret; |
| } |
| |
| ret = m_getBufferManager(PIPE_3AA_REPROCESSING, bufferManager[m_reprocessingFrameFactory->getNodeType(PIPE_3AP_REPROCESSING)], DST_BUFFER_DIRECTION); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getBufferManager() fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, PIPE_3AP_REPROCESSING, ret); |
| return ret; |
| } |
| #else |
| if (m_exynosCameraParameters->isReprocessing3aaIspOTF() == false) { |
| taaBufferManager[m_reprocessingFrameFactory->getNodeType(PIPE_3AA_REPROCESSING)] = m_bayerBufferMgr; |
| taaBufferManager[m_reprocessingFrameFactory->getNodeType(PIPE_3AP_REPROCESSING)] = m_ispReprocessingBufferMgr; |
| } else { |
| taaBufferManager[m_reprocessingFrameFactory->getNodeType(PIPE_3AA_REPROCESSING)] = m_bayerBufferMgr; |
| taaBufferManager[m_reprocessingFrameFactory->getNodeType(PIPE_ISPC_REPROCESSING)] = m_sccReprocessingBufferMgr; |
| |
| taaBufferManager[OUTPUT_NODE] = m_bayerBufferMgr; |
| taaBufferManager[CAPTURE_NODE] = m_sccReprocessingBufferMgr; |
| } |
| #endif |
| |
| ret = m_reprocessingFrameFactory->setBufferManagerToPipe(taaBufferManager, PIPE_3AA_REPROCESSING); |
| if (ret < 0) { |
| CLOGE("ERR(%s):m_reprocessingFrameFactory->setBufferManagerToPipe() failed", __FUNCTION__); |
| return ret; |
| } |
| |
| ispBufferManager[m_reprocessingFrameFactory->getNodeType(PIPE_ISP_REPROCESSING)] = m_ispReprocessingBufferMgr; |
| ispBufferManager[m_reprocessingFrameFactory->getNodeType(PIPE_ISPC_REPROCESSING)] = m_sccReprocessingBufferMgr; |
| |
| ret = m_reprocessingFrameFactory->setBufferManagerToPipe(ispBufferManager, PIPE_ISP_REPROCESSING); |
| if (ret < 0) { |
| CLOGE("ERR(%s):m_reprocessingFrameFactory->setBufferManagerToPipe() failed", __FUNCTION__); |
| return ret; |
| } |
| |
| ret = m_reprocessingFrameFactory->initPipes(); |
| if (ret < 0) { |
| CLOGE("ERR(%s):m_reprocessingFrameFactory->initPipes() failed", __FUNCTION__); |
| return ret; |
| } |
| |
| ret = m_reprocessingFrameFactory->preparePipes(); |
| if (ret < 0) { |
| CLOGE("ERR(%s):m_reprocessingFrameFactory preparePipe fail", __FUNCTION__); |
| return ret; |
| } |
| |
| /* stream on pipes */ |
| ret = m_reprocessingFrameFactory->startPipes(); |
| if (ret < 0) { |
| CLOGE("ERR(%s):m_reprocessingFrameFactory startPipe fail", __FUNCTION__); |
| return ret; |
| } |
| |
| m_zslPictureEnabled = true; |
| |
| /* |
| * Make remained frameFactory here. |
| * in case of reprocessing capture, make here. |
| */ |
| m_framefactoryThread->run(); |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_stopPictureInternal(void) |
| { |
| CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__); |
| int ret = 0; |
| |
| m_prePictureThread->join(); |
| m_pictureThread->join(); |
| |
| #ifdef SAMSUNG_LLS_DEBLUR |
| m_LDCaptureThread->join(); |
| #endif |
| |
| #ifdef SAMSUNG_DEBLUR |
| m_detectDeblurCaptureThread->join(); |
| m_deblurCaptureThread->join(); |
| #endif |
| |
| m_postPictureGscThread->join(); |
| |
| m_ThumbnailCallbackThread->join(); |
| |
| m_postPictureThread->join(); |
| m_jpegCallbackThread->join(); |
| |
| for (int threadNum = JPEG_SAVE_THREAD0; threadNum < JPEG_SAVE_THREAD_MAX_COUNT; threadNum++) { |
| m_jpegSaveThread[threadNum]->join(); |
| } |
| |
| if (m_zslPictureEnabled == true) { |
| ret = m_reprocessingFrameFactory->stopPipes(); |
| if (ret < 0) { |
| CLOGE("ERR(%s):m_reprocessingFrameFactory0>stopPipe() fail", __FUNCTION__); |
| } |
| } |
| |
| if (m_exynosCameraParameters->getHighResolutionCallbackMode() == true) { |
| m_highResolutionCallbackThread->stop(); |
| if (m_highResolutionCallbackQ != NULL) |
| m_highResolutionCallbackQ->sendCmd(WAKE_UP); |
| m_highResolutionCallbackThread->requestExitAndWait(); |
| } |
| |
| /* Clear frames & buffers which remain in capture processingQ */ |
| m_clearFrameQ(dstSccReprocessingQ, PIPE_SCC, DST_BUFFER_DIRECTION); |
| m_clearFrameQ(m_postPictureQ, PIPE_SCC, DST_BUFFER_DIRECTION); |
| m_clearFrameQ(dstJpegReprocessingQ, PIPE_JPEG, SRC_BUFFER_DIRECTION); |
| |
| dstIspReprocessingQ->release(); |
| dstGscReprocessingQ->release(); |
| |
| dstPostPictureGscQ->release(); |
| |
| m_ThumbnailPostCallbackQ->release(); |
| |
| dstJpegReprocessingQ->release(); |
| |
| m_jpegCallbackQ->release(); |
| |
| m_postviewCallbackQ->release(); |
| |
| m_thumbnailCallbackQ->release(); |
| |
| #ifdef SAMSUNG_DNG |
| m_dngCaptureQ->release(); |
| #endif |
| |
| #ifdef SAMSUNG_BD |
| m_BDbufferQ->release(); |
| |
| if(m_BDpluginHandle != NULL && m_BDstatus == BLUR_DETECTION_INIT) { |
| int ret = uni_plugin_deinit(m_BDpluginHandle); |
| if(ret < 0) { |
| CLOGE("[BD](%s[%d]): Plugin deinit failed!!", __FUNCTION__, __LINE__); |
| } |
| for(int i = 0; i < MAX_BD_BUFF_NUM; i++) { |
| if(m_BDbuffer[i].data != NULL){ |
| delete []m_BDbuffer[i].data; |
| } |
| } |
| } |
| m_BDstatus = BLUR_DETECTION_DEINIT; |
| #endif |
| #ifdef SAMSUNG_DEBLUR |
| m_detectDeblurCaptureQ->release(); |
| #endif |
| |
| for (int threadNum = JPEG_SAVE_THREAD0; threadNum < JPEG_SAVE_THREAD_MAX_COUNT; threadNum++) { |
| m_jpegSaveQ[threadNum]->release(); |
| } |
| |
| if (m_highResolutionCallbackQ->getSizeOfProcessQ() != 0){ |
| CLOGD("DEBUG(%s[%d]):m_highResolutionCallbackQ->getSizeOfProcessQ(%d). release the highResolutionCallbackQ.", |
| __FUNCTION__, __LINE__, m_highResolutionCallbackQ->getSizeOfProcessQ()); |
| m_highResolutionCallbackQ->release(); |
| } |
| |
| /* |
| * HACK : |
| * Just sleep for |
| * all picture-related thread(having m_postProcessList) is over. |
| * if not : |
| * m_clearList will delete frames. |
| * and then, the internal mutex of other thead's deleted frame |
| * will sleep forever (pThread's tech report) |
| * to remove this hack : |
| * stopPreview()'s burstPanorama-related sequence. |
| * stop all pipe -> wait all thread. -> clear all frameQ. |
| */ |
| usleep(5000); |
| |
| CLOGD("DEBUG(%s[%d]):clear postProcess(Picture) Frame list", __FUNCTION__, __LINE__); |
| |
| ret = m_clearList(&m_postProcessList); |
| if (ret < 0) { |
| CLOGE("ERR(%s):m_clearList fail", __FUNCTION__); |
| return ret; |
| } |
| |
| m_zslPictureEnabled = false; |
| |
| /* TODO: need timeout */ |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_startRecordingInternal(void) |
| { |
| int ret = 0; |
| |
| unsigned int bytesPerLine[EXYNOS_CAMERA_BUFFER_MAX_PLANES] = {0}; |
| unsigned int planeSize[EXYNOS_CAMERA_BUFFER_MAX_PLANES] = {0}; |
| int videoW = 0, videoH = 0; |
| int planeCount = 1; |
| int minBufferCount = 1; |
| int maxBufferCount = 1; |
| exynos_camera_buffer_type_t type = EXYNOS_CAMERA_BUFFER_ION_NONCACHED_TYPE; |
| buffer_manager_allocation_mode_t allocMode = BUFFER_MANAGER_ALLOCATION_SILENT; |
| int heapFd = 0; |
| |
| #ifdef SAMSUNG_LLV |
| if (m_exynosCameraParameters->getLLV() == true |
| #ifdef USE_LIVE_BROADCAST |
| && m_exynosCameraParameters->getPLBMode() == false |
| #endif |
| ) { |
| if(m_LLVpluginHandle != NULL){ |
| int HwPreviewW = 0, HwPreviewH = 0; |
| m_exynosCameraParameters->getHwPreviewSize(&HwPreviewW, &HwPreviewH); |
| |
| UniPluginBufferData_t pluginData; |
| UniPluginCameraInfo_t pluginCameraInfo; |
| pluginCameraInfo.CameraType = (UNI_PLUGIN_CAMERA_TYPE)getCameraId(); |
| pluginCameraInfo.SensorType = (UNI_PLUGIN_SENSOR_TYPE)m_cameraSensorId; |
| memset(&pluginData, 0, sizeof(UniPluginBufferData_t)); |
| pluginData.InWidth= HwPreviewW; |
| pluginData.InHeight= HwPreviewH; |
| if(m_LLVpluginHandle != NULL) { |
| uni_plugin_set(m_LLVpluginHandle, |
| LLV_PLUGIN_NAME, UNI_PLUGIN_INDEX_BUFFER_INFO, &pluginData); |
| } |
| int powerCtrl = UNI_PLUGIN_POWER_CONTROL_4; |
| if(m_LLVpluginHandle != NULL) { |
| uni_plugin_set(m_LLVpluginHandle, |
| LLV_PLUGIN_NAME, UNI_PLUGIN_INDEX_POWER_CONTROL, &powerCtrl); |
| uni_plugin_set(m_LLVpluginHandle, |
| LLV_PLUGIN_NAME, UNI_PLUGIN_INDEX_CAMERA_INFO, &pluginCameraInfo); |
| } |
| uni_plugin_init(m_LLVpluginHandle); |
| |
| m_LLVstatus = LLV_INIT; |
| } |
| } |
| |
| #endif |
| |
| m_exynosCameraParameters->getVideoSize(&videoW, &videoH); |
| CLOGD("DEBUG(%s[%d]):videoSize = %d x %d", __FUNCTION__, __LINE__, videoW, videoH); |
| |
| m_doCscRecording = true; |
| if (m_exynosCameraParameters->doCscRecording() == true) { |
| m_recordingBufferCount = m_exynosconfig->current->bufInfo.num_recording_buffers; |
| CLOGI("INFO(%s[%d]):do Recording CSC !!! m_recordingBufferCount(%d)", __FUNCTION__, __LINE__, m_recordingBufferCount); |
| } else { |
| m_doCscRecording = false; |
| m_recordingBufferCount = m_exynosconfig->current->bufInfo.num_preview_buffers; |
| CLOGI("INFO(%s[%d]):skip Recording CSC !!! m_recordingBufferCount(%d->%d)", |
| __FUNCTION__, __LINE__, m_exynosconfig->current->bufInfo.num_recording_buffers, m_recordingBufferCount); |
| } |
| |
| /* clear previous recording frame */ |
| CLOGD("DEBUG(%s[%d]):Recording m_recordingProcessList(%d) IN", |
| __FUNCTION__, __LINE__, (int)m_recordingProcessList.size()); |
| m_recordingListLock.lock(); |
| ret = m_clearList(&m_recordingProcessList); |
| if (ret < 0) { |
| CLOGE("ERR(%s):m_clearList fail", __FUNCTION__); |
| } |
| m_recordingListLock.unlock(); |
| CLOGD("DEBUG(%s[%d]):Recording m_recordingProcessList(%d) OUT", |
| __FUNCTION__, __LINE__, (int)m_recordingProcessList.size()); |
| |
| for (int32_t i = 0; i < m_recordingBufferCount; i++) { |
| m_recordingTimeStamp[i] = 0L; |
| m_recordingBufAvailable[i] = true; |
| } |
| |
| /* alloc recording Callback Heap */ |
| m_recordingCallbackHeap = m_getMemoryCb(-1, sizeof(VideoNativeHandleMetadata), m_recordingBufferCount, &heapFd); |
| if (!m_recordingCallbackHeap || m_recordingCallbackHeap->data == MAP_FAILED) { |
| CLOGE("ERR(%s[%d]):m_getMemoryCb(%d) fail", __FUNCTION__, __LINE__, (int)sizeof(struct addrs)); |
| ret = INVALID_OPERATION; |
| goto func_exit; |
| } |
| |
| if (m_doCscRecording == true) { |
| /* alloc recording Image buffer */ |
| planeSize[0] = ROUND_UP(videoW, CAMERA_MAGIC_ALIGN) * ROUND_UP(videoH, CAMERA_MAGIC_ALIGN) + MFC_7X_BUFFER_OFFSET; |
| planeSize[1] = ROUND_UP(videoW, CAMERA_MAGIC_ALIGN) * ROUND_UP(videoH / 2, CAMERA_MAGIC_ALIGN) + MFC_7X_BUFFER_OFFSET; |
| planeCount = 2; |
| if( m_exynosCameraParameters->getHighSpeedRecording() == true) |
| minBufferCount = m_recordingBufferCount; |
| else |
| minBufferCount = 1; |
| |
| maxBufferCount = m_recordingBufferCount; |
| |
| ret = m_allocBuffers(m_recordingBufferMgr, planeCount, planeSize, bytesPerLine, minBufferCount, maxBufferCount, type, allocMode, false, true); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_recordingBufferMgr m_allocBuffers(minBufferCount=%d, maxBufferCount=%d) fail", |
| __FUNCTION__, __LINE__, minBufferCount, maxBufferCount); |
| } |
| |
| } |
| |
| if (m_doCscRecording == true) { |
| int recPipeId = PIPE_GSC_VIDEO; |
| |
| m_previewFrameFactory->startThread(recPipeId); |
| |
| if (m_recordingQ->getSizeOfProcessQ() > 0) { |
| CLOGE("ERR(%s[%d]):m_startRecordingInternal recordingQ(%d)", __FUNCTION__, __LINE__, m_recordingQ->getSizeOfProcessQ()); |
| /* |
| * just empty q on m_recordingQ. |
| * m_clearList() can make deadlock by accessing frame |
| * deleted on m_stopRecordingInternal() |
| */ |
| /* m_clearList(m_recordingQ); */ |
| m_recordingQ->release(); |
| } |
| |
| m_recordingThread->run(); |
| } |
| |
| func_exit: |
| |
| return ret; |
| } |
| |
| status_t ExynosCamera::m_stopRecordingInternal(void) |
| { |
| int ret = 0; |
| if (m_doCscRecording == true) { |
| int recPipeId = PIPE_GSC_VIDEO; |
| |
| { |
| Mutex::Autolock lock(m_recordingStopLock); |
| m_previewFrameFactory->stopPipe(recPipeId); |
| } |
| |
| m_recordingQ->sendCmd(WAKE_UP); |
| |
| m_recordingThread->requestExitAndWait(); |
| m_recordingQ->release(); |
| m_recordingBufferMgr->deinit(); |
| } else { |
| CLOGI("INFO(%s[%d]):reset m_recordingBufferCount(%d->%d)", |
| __FUNCTION__, __LINE__, m_recordingBufferCount, m_exynosconfig->current->bufInfo.num_recording_buffers); |
| m_recordingBufferCount = m_exynosconfig->current->bufInfo.num_recording_buffers; |
| } |
| |
| /* Checking all frame(buffer) released from Media recorder */ |
| int sleepUsecs = 33300; |
| int retryCount = 3; /* 33.3ms*3 = 100ms */ |
| bool allBufferReleased = true; |
| |
| for (int i = 0; i < retryCount; i++) { |
| allBufferReleased = true; |
| |
| for (int bufferIndex = 0; bufferIndex < m_recordingBufferCount; bufferIndex++) { |
| if (m_recordingBufAvailable[bufferIndex] == false) { |
| CLOGW("WRN(%s[%d]):Media recorder doesn't release frame(buffer), index(%d)", |
| __FUNCTION__, __LINE__, bufferIndex); |
| allBufferReleased = false; |
| } |
| } |
| |
| if(allBufferReleased == true) { |
| break; |
| } |
| |
| usleep(sleepUsecs); |
| } |
| |
| if (allBufferReleased == false) { |
| CLOGE("ERR(%s[%d]):Media recorder doesn't release frame(buffer) all!!", __FUNCTION__, __LINE__); |
| } |
| |
| if (m_recordingCallbackHeap != NULL) { |
| m_recordingCallbackHeap->release(m_recordingCallbackHeap); |
| m_recordingCallbackHeap = NULL; |
| } |
| |
| #ifdef SAMSUNG_LLV |
| if (m_LLVstatus == LLV_INIT) { |
| m_LLVstatus = LLV_STOPPED; |
| } |
| #endif |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_restartPreviewInternal(void) |
| { |
| CLOGI("INFO(%s[%d]): Internal restart preview", __FUNCTION__, __LINE__); |
| int ret = 0; |
| int err = 0; |
| |
| m_flagThreadStop = true; |
| m_disablePreviewCB = true; |
| |
| m_startPictureInternalThread->join(); |
| |
| /* release about frameFactory */ |
| m_framefactoryThread->stop(); |
| m_frameFactoryQ->sendCmd(WAKE_UP); |
| m_framefactoryThread->requestExitAndWait(); |
| m_frameFactoryQ->release(); |
| |
| m_startPictureBufferThread->join(); |
| |
| if (m_previewFrameFactory != NULL) |
| m_previewFrameFactory->setStopFlag(); |
| |
| m_mainThread->requestExitAndWait(); |
| |
| ret = m_stopPictureInternal(); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):m_stopPictureInternal fail", __FUNCTION__, __LINE__); |
| |
| m_zoomPreviwWithCscThread->stop(); |
| m_zoomPreviwWithCscQ->sendCmd(WAKE_UP); |
| m_zoomPreviwWithCscThread->requestExitAndWait(); |
| |
| m_previewThread->stop(); |
| if(m_previewQ != NULL) |
| m_previewQ->sendCmd(WAKE_UP); |
| m_previewThread->requestExitAndWait(); |
| |
| if (m_exynosCameraParameters->isFlite3aaOtf() == true) { |
| m_mainSetupQThread[INDEX(PIPE_FLITE)]->stop(); |
| m_mainSetupQ[INDEX(PIPE_FLITE)]->sendCmd(WAKE_UP); |
| m_mainSetupQThread[INDEX(PIPE_FLITE)]->requestExitAndWait(); |
| |
| if (m_mainSetupQThread[INDEX(PIPE_3AC)] != NULL) { |
| m_mainSetupQThread[INDEX(PIPE_3AC)]->stop(); |
| m_mainSetupQ[INDEX(PIPE_3AC)]->sendCmd(WAKE_UP); |
| m_mainSetupQThread[INDEX(PIPE_3AC)]->requestExitAndWait(); |
| } |
| |
| m_mainSetupQThread[INDEX(PIPE_3AA)]->stop(); |
| m_mainSetupQ[INDEX(PIPE_3AA)]->sendCmd(WAKE_UP); |
| m_mainSetupQThread[INDEX(PIPE_3AA)]->requestExitAndWait(); |
| |
| if (m_mainSetupQThread[INDEX(PIPE_ISP)] != NULL) { |
| m_mainSetupQThread[INDEX(PIPE_ISP)]->stop(); |
| m_mainSetupQ[INDEX(PIPE_ISP)]->sendCmd(WAKE_UP); |
| m_mainSetupQThread[INDEX(PIPE_ISP)]->requestExitAndWait(); |
| } |
| |
| /* Comment out, because it included ISP */ |
| /* |
| m_mainSetupQThread[INDEX(PIPE_SCP)]->stop(); |
| m_mainSetupQ[INDEX(PIPE_SCP)]->sendCmd(WAKE_UP); |
| m_mainSetupQThread[INDEX(PIPE_SCP)]->requestExitAndWait(); |
| */ |
| |
| m_clearList(m_mainSetupQ[INDEX(PIPE_FLITE)]); |
| m_clearList(m_mainSetupQ[INDEX(PIPE_3AA)]); |
| m_clearList(m_mainSetupQ[INDEX(PIPE_ISP)]); |
| /* Comment out, because it included ISP */ |
| /* m_clearList(m_mainSetupQ[INDEX(PIPE_SCP)]); */ |
| |
| m_mainSetupQ[INDEX(PIPE_FLITE)]->release(); |
| m_mainSetupQ[INDEX(PIPE_3AA)]->release(); |
| m_mainSetupQ[INDEX(PIPE_ISP)]->release(); |
| /* Comment out, because it included ISP */ |
| /* m_mainSetupQ[INDEX(PIPE_SCP)]->release(); */ |
| } else { |
| if (m_mainSetupQThread[INDEX(PIPE_FLITE)] != NULL) { |
| m_mainSetupQThread[INDEX(PIPE_FLITE)]->stop(); |
| m_mainSetupQ[INDEX(PIPE_FLITE)]->sendCmd(WAKE_UP); |
| m_mainSetupQThread[INDEX(PIPE_FLITE)]->requestExitAndWait(); |
| m_clearList(m_mainSetupQ[INDEX(PIPE_FLITE)]); |
| m_mainSetupQ[INDEX(PIPE_FLITE)]->release(); |
| } |
| } |
| |
| ret = m_stopPreviewInternal(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_stopPreviewInternal fail", __FUNCTION__, __LINE__); |
| err = ret; |
| } |
| |
| #ifdef SUPPORT_SW_VDIS |
| if(m_swVDIS_Mode) { |
| if (m_swVDIS_BufferMgr != NULL) |
| m_swVDIS_BufferMgr->deinit(); |
| |
| if(m_exynosCameraParameters->increaseMaxBufferOfPreview()) { |
| m_exynosCameraParameters->setPreviewBufferCount(NUM_PREVIEW_BUFFERS + NUM_PREVIEW_SPARE_BUFFERS); |
| m_exynosconfig->current->bufInfo.num_preview_buffers = NUM_PREVIEW_BUFFERS + NUM_PREVIEW_SPARE_BUFFERS; |
| VDIS_LOG("VDIS_HAL: Preview Buffer Count Change to %d", NUM_PREVIEW_BUFFERS + NUM_PREVIEW_SPARE_BUFFERS); |
| } else { |
| m_exynosCameraParameters->setPreviewBufferCount(NUM_PREVIEW_BUFFERS); |
| m_exynosconfig->current->bufInfo.num_preview_buffers = NUM_PREVIEW_BUFFERS; |
| VDIS_LOG("VDIS_HAL: Preview Buffer Count Change to %d", NUM_PREVIEW_BUFFERS); |
| } |
| } |
| #endif /*SUPPORT_SW_VDIS*/ |
| |
| /* skip to free and reallocate buffers */ |
| if (m_bayerBufferMgr != NULL) { |
| m_bayerBufferMgr->resetBuffers(); |
| } |
| #ifdef SAMSUNG_DNG |
| if (m_fliteBufferMgr != NULL) { |
| m_fliteBufferMgr->resetBuffers(); |
| } |
| #endif |
| if (m_3aaBufferMgr != NULL) { |
| m_3aaBufferMgr->resetBuffers(); |
| } |
| if (m_ispBufferMgr != NULL) { |
| m_ispBufferMgr->resetBuffers(); |
| } |
| if (m_hwDisBufferMgr != NULL) { |
| m_hwDisBufferMgr->resetBuffers(); |
| } |
| if (m_sccBufferMgr != NULL) { |
| m_sccBufferMgr->resetBuffers(); |
| } |
| |
| if (m_highResolutionCallbackBufferMgr != NULL) { |
| m_highResolutionCallbackBufferMgr->resetBuffers(); |
| } |
| |
| /* skip to free and reallocate buffers */ |
| if (m_ispReprocessingBufferMgr != NULL) { |
| m_ispReprocessingBufferMgr->resetBuffers(); |
| } |
| if (m_sccReprocessingBufferMgr != NULL) { |
| m_sccReprocessingBufferMgr->resetBuffers(); |
| } |
| |
| if (m_gscBufferMgr != NULL) { |
| m_gscBufferMgr->resetBuffers(); |
| } |
| if (m_jpegBufferMgr != NULL) { |
| m_jpegBufferMgr->resetBuffers(); |
| } |
| if (m_recordingBufferMgr != NULL) { |
| m_recordingBufferMgr->resetBuffers(); |
| } |
| |
| /* realloc callback buffers */ |
| if (m_scpBufferMgr != NULL) { |
| m_scpBufferMgr->deinit(); |
| m_scpBufferMgr->setBufferCount(0); |
| } |
| if (m_previewCallbackBufferMgr != NULL) { |
| m_previewCallbackBufferMgr->deinit(); |
| } |
| if (m_zoomScalerBufferMgr != NULL) { |
| m_zoomScalerBufferMgr->deinit(); |
| } |
| |
| if (m_captureSelector != NULL) { |
| m_captureSelector->release(); |
| } |
| if (m_sccCaptureSelector != NULL) { |
| m_sccCaptureSelector->release(); |
| } |
| |
| if( m_exynosCameraParameters->getHighSpeedRecording() && m_exynosCameraParameters->getReallocBuffer() ) { |
| CLOGD("DEBUG(%s): realloc buffer all buffer deinit ", __FUNCTION__); |
| if (m_bayerBufferMgr != NULL) { |
| m_bayerBufferMgr->deinit(); |
| } |
| if (m_3aaBufferMgr != NULL) { |
| m_3aaBufferMgr->deinit(); |
| } |
| if (m_ispBufferMgr != NULL) { |
| m_ispBufferMgr->deinit(); |
| } |
| |
| if (m_sccBufferMgr != NULL) { |
| m_sccBufferMgr->deinit(); |
| } |
| /* |
| if (m_highResolutionCallbackBufferMgr != NULL) { |
| m_highResolutionCallbackBufferMgr->deinit(); |
| } |
| */ |
| if (m_gscBufferMgr != NULL) { |
| m_gscBufferMgr->deinit(); |
| } |
| if (m_jpegBufferMgr != NULL) { |
| m_jpegBufferMgr->deinit(); |
| } |
| if (m_recordingBufferMgr != NULL) { |
| m_recordingBufferMgr->deinit(); |
| } |
| } |
| |
| if (m_exynosCameraParameters->getTpuEnabledMode() == true) { |
| if (m_hwDisBufferMgr != NULL) { |
| m_hwDisBufferMgr->deinit(); |
| } |
| } |
| |
| m_flagThreadStop = false; |
| |
| ret = setPreviewWindow(m_previewWindow); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setPreviewWindow fail", __FUNCTION__, __LINE__); |
| err = ret; |
| } |
| |
| CLOGI("INFO(%s[%d]):setBuffersThread is run", __FUNCTION__, __LINE__); |
| m_setBuffersThread->run(PRIORITY_DEFAULT); |
| m_setBuffersThread->join(); |
| |
| if (m_isSuccessedBufferAllocation == false) { |
| CLOGE("ERR(%s[%d]):m_setBuffersThread() failed", __FUNCTION__, __LINE__); |
| err = INVALID_OPERATION; |
| } |
| |
| #ifdef START_PICTURE_THREAD |
| m_startPictureInternalThread->join(); |
| #endif |
| m_startPictureBufferThread->join(); |
| |
| if (m_exynosCameraParameters->isReprocessing() == true) { |
| #ifdef START_PICTURE_THREAD |
| m_startPictureInternalThread->run(PRIORITY_DEFAULT); |
| #endif |
| } else { |
| m_pictureFrameFactory = m_previewFrameFactory; |
| CLOGD("DEBUG(%s[%d]):FrameFactory(pictureFrameFactory) created", __FUNCTION__, __LINE__); |
| |
| /* |
| * Make remained frameFactory here. |
| * in case of SCC capture, make here. |
| */ |
| m_framefactoryThread->run(); |
| } |
| |
| ret = m_startPreviewInternal(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_startPreviewInternal fail", __FUNCTION__, __LINE__); |
| err = ret; |
| } |
| |
| /* setup frame thread */ |
| if (m_exynosCameraParameters->getDualMode() == true && getCameraId() == CAMERA_ID_FRONT) { |
| CLOGD("DEBUG(%s[%d]):setupThread Thread start pipeId(%d)", __FUNCTION__, __LINE__, PIPE_FLITE); |
| m_mainSetupQThread[INDEX(PIPE_FLITE)]->run(PRIORITY_URGENT_DISPLAY); |
| } else { |
| switch (m_exynosCameraParameters->getReprocessingBayerMode()) { |
| case REPROCESSING_BAYER_MODE_PURE_ALWAYS_ON: |
| m_mainSetupQ[INDEX(PIPE_FLITE)]->setup(NULL); |
| CLOGD("DEBUG(%s[%d]):setupThread Thread start pipeId(%d)", __FUNCTION__, __LINE__, PIPE_FLITE); |
| m_mainSetupQThread[INDEX(PIPE_FLITE)]->run(PRIORITY_URGENT_DISPLAY); |
| break; |
| case REPROCESSING_BAYER_MODE_PURE_DYNAMIC: |
| CLOGD("DEBUG(%s[%d]):setupThread with List pipeId(%d)", __FUNCTION__, __LINE__, PIPE_FLITE); |
| m_mainSetupQ[INDEX(PIPE_FLITE)]->setup(m_mainSetupQThread[INDEX(PIPE_FLITE)]); |
| break; |
| default: |
| CLOGI("INFO(%s[%d]):setupThread not started pipeID(%d)", __FUNCTION__, __LINE__, PIPE_FLITE); |
| break; |
| } |
| CLOGD("DEBUG(%s[%d]):setupThread Thread start pipeId(%d)", __FUNCTION__, __LINE__, PIPE_3AA); |
| m_mainSetupQThread[INDEX(PIPE_3AA)]->run(PRIORITY_URGENT_DISPLAY); |
| } |
| |
| #ifdef SAMSUNG_DNG |
| if (m_exynosCameraParameters->getDNGCaptureModeOn()) { |
| CLOGD("[DNG](%s[%d]):setupThread with List pipeId(%d)", __FUNCTION__, __LINE__, PIPE_FLITE); |
| m_mainSetupQ[INDEX(PIPE_FLITE)]->setup(m_mainSetupQThread[INDEX(PIPE_FLITE)]); |
| } |
| #endif |
| |
| if (m_facedetectThread->isRunning() == false) |
| m_facedetectThread->run(); |
| |
| m_disablePreviewCB = false; |
| m_previewThread->run(PRIORITY_DISPLAY); |
| |
| m_mainThread->run(PRIORITY_DEFAULT); |
| m_startPictureInternalThread->join(); |
| |
| if (m_exynosCameraParameters->getZoomPreviewWIthScaler() == true) { |
| CLOGD("DEBUG(%s[%d]):ZoomPreview with Scaler Thread start", __FUNCTION__, __LINE__); |
| m_zoomPreviwWithCscThread->run(PRIORITY_DEFAULT); |
| } |
| |
| |
| return err; |
| } |
| |
| bool ExynosCamera::m_mainThreadQSetup3AA() |
| { |
| #ifdef DEBUG |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| #endif |
| |
| int ret = 0; |
| bool loop = true; |
| int pipeId_3AA = PIPE_3AA; |
| int pipeId_3AC = PIPE_3AC; |
| int pipeId_ISP = PIPE_ISP; |
| int pipeId_DIS = PIPE_DIS; |
| int pipeIdCsc = 0; |
| int maxbuffers = 0; |
| |
| ExynosCameraBuffer buffer; |
| ExynosCameraFrame *frame = NULL; |
| ExynosCameraFrame *newframe = NULL; |
| nsecs_t timeStamp = 0; |
| int frameCount = -1; |
| |
| CLOGV("INFO(%s[%d]):wait previewCancelQ", __FUNCTION__, __LINE__); |
| ret = m_mainSetupQ[INDEX(pipeId_3AA)]->waitAndPopProcessQ(&frame); |
| if (m_flagThreadStop == true) { |
| CLOGI("INFO(%s[%d]):m_flagThreadStop(%d)", __FUNCTION__, __LINE__, m_flagThreadStop); |
| goto func_exit; |
| } |
| |
| if (ret < 0) { |
| if (ret == TIMED_OUT) { |
| CLOGW("WARN(%s):wait timeout", __FUNCTION__); |
| } else { |
| CLOGE("ERR(%s):wait and pop fail, ret(%d)", __FUNCTION__, ret); |
| /* TODO: doing exception handling */ |
| } |
| goto func_exit; |
| } |
| |
| if (frame == NULL) { |
| CLOGE("ERR(%s[%d]):frame is NULL", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| ret = generateFrame(m_3aa_ispFrameCount, &newframe); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):generateFrame fail", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| if (newframe == NULL) { |
| CLOGE("ERR(%s[%d]):frame is NULL", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| ret = m_setupEntity(pipeId_3AA, newframe); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail", __FUNCTION__, __LINE__); |
| } |
| |
| if (m_exynosCameraParameters->is3aaIspOtf() == true) { |
| m_previewFrameFactory->setFrameDoneQToPipe(m_pipeFrameDoneQ, pipeId_3AA); |
| |
| if (m_exynosCameraParameters->getTpuEnabledMode() == true) |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, pipeId_DIS); |
| } else { |
| m_previewFrameFactory->setFrameDoneQToPipe(m_pipeFrameDoneQ, pipeId_3AA); |
| |
| if (m_exynosCameraParameters->getTpuEnabledMode() == true) { |
| m_previewFrameFactory->setFrameDoneQToPipe(m_pipeFrameDoneQ, pipeId_ISP); |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, pipeId_DIS); |
| } else { |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, pipeId_ISP); |
| } |
| } |
| |
| m_previewFrameFactory->pushFrameToPipe(&newframe, pipeId_3AA); |
| |
| m_3aa_ispFrameCount++; |
| |
| func_exit: |
| if( frame != NULL ) { |
| frame->decRef(); |
| m_frameMgr->deleteFrame(frame);; |
| frame = NULL; |
| } |
| |
| return loop; |
| } |
| |
| bool ExynosCamera::m_mainThreadQSetup3AA_ISP() |
| { |
| #ifdef DEBUG |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| #endif |
| |
| int ret = 0; |
| bool loop = true; |
| int pipeId = PIPE_3AA_ISP; |
| int pipeIdCsc = 0; |
| int maxbuffers = 0; |
| |
| ExynosCameraBuffer buffer; |
| ExynosCameraFrame *frame = NULL; |
| ExynosCameraFrame *newframe = NULL; |
| nsecs_t timeStamp = 0; |
| int frameCount = -1; |
| |
| CLOGV("INFO(%s[%d]):wait previewCancelQ", __FUNCTION__, __LINE__); |
| ret = m_mainSetupQ[INDEX(pipeId)]->waitAndPopProcessQ(&frame); |
| if (m_flagThreadStop == true) { |
| CLOGI("INFO(%s[%d]):m_flagThreadStop(%d)", __FUNCTION__, __LINE__, m_flagThreadStop); |
| goto func_exit; |
| } |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto func_exit; |
| } |
| |
| if (frame == NULL) { |
| CLOGE("ERR(%s[%d]):frame is NULL", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| while (m_3aaBufferMgr->getNumOfAvailableBuffer() > 0 && |
| m_ispBufferMgr->getNumOfAvailableBuffer() > 0) { |
| ret = generateFrame(m_3aa_ispFrameCount, &newframe); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):generateFrame fail", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| if (newframe == NULL) { |
| CLOGE("ERR(%s[%d]):frame is NULL", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| ret = m_setupEntity(pipeId, newframe); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail", __FUNCTION__, __LINE__); |
| } |
| |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, pipeId); |
| m_previewFrameFactory->pushFrameToPipe(&newframe, pipeId); |
| |
| m_3aa_ispFrameCount++; |
| |
| } |
| |
| func_exit: |
| if( frame != NULL ) { |
| frame->decRef(); |
| m_frameMgr->deleteFrame(frame);; |
| frame = NULL; |
| } |
| |
| /* |
| if (m_mainSetupQ[INDEX(pipeId)]->getSizeOfProcessQ() <= 0) |
| loop = false; |
| */ |
| |
| return loop; |
| } |
| |
| bool ExynosCamera::m_mainThreadQSetupISP() |
| { |
| #ifdef DEBUG |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| #endif |
| |
| int ret = 0; |
| bool loop = false; |
| int pipeId = PIPE_ISP; |
| |
| ExynosCameraBuffer buffer; |
| ExynosCameraFrame *frame = NULL; |
| nsecs_t timeStamp = 0; |
| int frameCount = -1; |
| |
| CLOGV("INFO(%s[%d]):wait previewCancelQ", __FUNCTION__, __LINE__); |
| ret = m_mainSetupQ[INDEX(pipeId)]->waitAndPopProcessQ(&frame); |
| if (m_flagThreadStop == true) { |
| CLOGI("INFO(%s[%d]):m_flagThreadStop(%d)", __FUNCTION__, __LINE__, m_flagThreadStop); |
| goto func_exit; |
| } |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto func_exit; |
| } |
| |
| if (frame == NULL) { |
| CLOGE("ERR(%s[%d]):frame is NULL", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| func_exit: |
| if( frame != NULL ) { |
| frame->decRef(); |
| m_frameMgr->deleteFrame(frame); |
| frame = NULL; |
| } |
| |
| if (m_mainSetupQ[INDEX(pipeId)]->getSizeOfProcessQ() > 0) |
| loop = true; |
| |
| return loop; |
| } |
| |
| bool ExynosCamera::m_mainThreadQSetupFLITE() |
| { |
| #ifdef DEBUG |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| #endif |
| |
| int ret = 0; |
| bool loop = true; |
| int pipeId = PIPE_FLITE; |
| int pipeIdCsc = 0; |
| int maxbuffers = 0; |
| |
| ExynosCameraBuffer buffer; |
| ExynosCameraFrame *frame = NULL; |
| ExynosCameraFrame *newframe = NULL; |
| nsecs_t timeStamp = 0; |
| int frameCount = -1; |
| ExynosCameraBufferManager *bufMgr; |
| #ifdef SAMSUNG_DNG |
| int dstbufferIndex = 0; |
| |
| buffer.index = -2; |
| dstbufferIndex = -1; |
| |
| if (m_exynosCameraParameters->getDNGCaptureModeOn()) { |
| loop = false; |
| } |
| #endif |
| |
| CLOGV("INFO(%s[%d]):wait previewCancelQ", __FUNCTION__, __LINE__); |
| ret = m_mainSetupQ[INDEX(pipeId)]->waitAndPopProcessQ(&frame); |
| if (m_flagThreadStop == true) { |
| CLOGI("INFO(%s[%d]):m_flagThreadStop(%d)", __FUNCTION__, __LINE__, m_flagThreadStop); |
| goto func_exit; |
| } |
| if (ret < 0) { |
| if (ret == TIMED_OUT) { |
| CLOGW("WARN(%s):wait timeout", __FUNCTION__); |
| } else { |
| CLOGE("ERR(%s):wait and pop fail, ret(%d)", __FUNCTION__, ret); |
| /* TODO: doing exception handling */ |
| } |
| goto func_exit; |
| } |
| |
| if (frame == NULL) { |
| CLOGE("ERR(%s[%d]):frame is NULL", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| #ifdef SAMSUNG_DNG |
| if (m_exynosCameraParameters->getDNGCaptureModeOn()) { |
| bufMgr = m_fliteBufferMgr; |
| } else |
| #endif |
| { |
| bufMgr = m_bayerBufferMgr; |
| } |
| |
| if (bufMgr->getNumOfAvailableBuffer() > 0) { |
| ret = generateFrame(m_fliteFrameCount, &newframe); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):generateFrame fail", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| #ifdef SAMSUNG_DNG |
| if (m_exynosCameraParameters->getDNGCaptureModeOn()) { |
| m_fliteBufferMgr->getBuffer(&dstbufferIndex, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL, &buffer); |
| ret = m_setupEntity(pipeId, newframe, NULL, &buffer); |
| CLOGV("[DNG](%s[%d]): m_fliteFrameCount(%d) index(%d)", __FUNCTION__, __LINE__, m_fliteFrameCount,buffer.index); |
| } else |
| #endif |
| { |
| ret = m_setupEntity(pipeId, newframe); |
| } |
| |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail", __FUNCTION__, __LINE__); |
| } |
| ret = newframe->getDstBuffer(pipeId, &buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, pipeId); |
| m_previewFrameFactory->pushFrameToPipe(&newframe, pipeId); |
| |
| m_fliteFrameCount++; |
| } |
| |
| func_exit: |
| if( frame != NULL ) { |
| frame->decRef(); |
| m_frameMgr->deleteFrame(frame);; |
| frame = NULL; |
| } |
| |
| /* |
| if (m_mainSetupQ[INDEX(pipeId)]->getSizeOfProcessQ() <= 0) |
| loop = false; |
| */ |
| |
| return loop; |
| } |
| |
| bool ExynosCamera::m_mainThreadQSetup3AC() |
| { |
| #ifdef DEBUG |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| #endif |
| |
| int ret = 0; |
| bool loop = true; |
| int pipeId = PIPE_3AC; |
| int pipeIdCsc = 0; |
| int maxbuffers = 0; |
| |
| ExynosCameraBuffer buffer; |
| ExynosCameraFrame *frame = NULL; |
| ExynosCameraFrame *newframe = NULL; |
| nsecs_t timeStamp = 0; |
| int frameCount = -1; |
| |
| CLOGV("INFO(%s[%d]):wait previewCancelQ", __FUNCTION__, __LINE__); |
| ret = m_mainSetupQ[INDEX(pipeId)]->waitAndPopProcessQ(&frame); |
| if (m_flagThreadStop == true) { |
| CLOGI("INFO(%s[%d]):m_flagThreadStop(%d)", __FUNCTION__, __LINE__, m_flagThreadStop); |
| goto func_exit; |
| } |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto func_exit; |
| } |
| |
| if (frame == NULL) { |
| CLOGE("ERR(%s[%d]):frame is NULL", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| if (m_bayerBufferMgr->getNumOfAvailableBuffer() > 0) { |
| do { |
| ret = generateFrame(m_fliteFrameCount, &newframe); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):generateFrame fail", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| ret = m_setupEntity(pipeId, newframe); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail", __FUNCTION__, __LINE__); |
| } |
| ret = newframe->getDstBuffer(pipeId, &buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, pipeId); |
| m_previewFrameFactory->pushFrameToPipe(&newframe, pipeId); |
| |
| m_fliteFrameCount++; |
| } while (0 < m_bayerBufferMgr->getNumOfAvailableBuffer()); |
| } |
| |
| func_exit: |
| if( frame != NULL ) { |
| frame->decRef(); |
| m_frameMgr->deleteFrame(frame);; |
| } |
| |
| return loop; |
| } |
| |
| bool ExynosCamera::m_mainThreadQSetupSCP() |
| { |
| #ifdef DEBUG |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| #endif |
| |
| int ret = 0; |
| bool loop = true; |
| int pipeId = PIPE_SCP; |
| int pipeIdCsc = 0; |
| int maxbuffers = 0; |
| |
| camera2_node_group node_group_info_isp; |
| ExynosCameraBuffer resultBuffer; |
| ExynosCameraFrame *frame = NULL; |
| ExynosCameraFrame *newframe = NULL; |
| nsecs_t timeStamp = 0; |
| int frameCount = -1; |
| int frameGen = 1; |
| |
| CLOGV("INFO(%s[%d]):wait previewCancelQ", __FUNCTION__, __LINE__); |
| ret = m_mainSetupQ[INDEX(pipeId)]->waitAndPopProcessQ(&frame); |
| if (m_flagThreadStop == true) { |
| CLOGI("INFO(%s[%d]):m_flagThreadStop(%d)", __FUNCTION__, __LINE__, m_flagThreadStop); |
| goto func_exit; |
| } |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto func_exit; |
| } |
| |
| if (frame == NULL) { |
| CLOGE("ERR(%s[%d]):frame is NULL", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| ret = generateFrameSccScp(pipeId, &m_scpFrameCount, &newframe); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):generateFrameSccScp fail", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| if( frame->getFrameState() == FRAME_STATE_SKIPPED ) { |
| frame->getDstBuffer(pipeId, &resultBuffer); |
| m_setupEntity(pipeId, newframe, NULL, &resultBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail", __FUNCTION__, __LINE__); |
| } |
| newframe->getDstBuffer(pipeId, &resultBuffer); |
| } else { |
| ret = m_setupEntity(pipeId, newframe); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail", __FUNCTION__, __LINE__); |
| } |
| newframe->getDstBuffer(pipeId, &resultBuffer); |
| } |
| |
| /*check preview drop...*/ |
| newframe->getDstBuffer(pipeId, &resultBuffer); |
| if (resultBuffer.index < 0) { |
| newframe->setRequest(pipeId, false); |
| newframe->getNodeGroupInfo(&node_group_info_isp, PERFRAME_INFO_ISP); |
| node_group_info_isp.capture[PERFRAME_BACK_SCP_POS].request = 0; |
| newframe->storeNodeGroupInfo(&node_group_info_isp, PERFRAME_INFO_ISP); |
| m_previewFrameFactory->dump(); |
| |
| if (m_getRecordingEnabled() == true |
| && m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_VIDEO_FRAME) |
| && m_exynosCameraParameters->getHighSpeedRecording() == false) { |
| CLOGW("WARN(%s[%d]):Recording preview drop. Failed to get preview buffer. FrameSkipCount(%d)", |
| __FUNCTION__, __LINE__, FRAME_SKIP_COUNT_RECORDING); |
| /* when preview buffer is not ready, we should drop preview to make preview buffer ready */ |
| m_exynosCameraParameters->setFrameSkipCount(FRAME_SKIP_COUNT_RECORDING); |
| } else { |
| CLOGW("WARN(%s[%d]):Preview drop. Failed to get preview buffer. FrameSkipCount (%d)", |
| __FUNCTION__, __LINE__, FRAME_SKIP_COUNT_PREVIEW); |
| /* when preview buffer is not ready, we should drop preview to make preview buffer ready */ |
| m_exynosCameraParameters->setFrameSkipCount(FRAME_SKIP_COUNT_PREVIEW); |
| } |
| } |
| |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, pipeId); |
| m_previewFrameFactory->pushFrameToPipe(&newframe, pipeId); |
| |
| m_scpFrameCount++; |
| |
| func_exit: |
| if( frame != NULL ) { |
| frame->decRef(); |
| m_frameMgr->deleteFrame(frame); |
| frame = NULL; |
| } |
| |
| /* |
| if (m_mainSetupQ[INDEX(pipeId)]->getSizeOfProcessQ() <= 0) |
| loop = false; |
| */ |
| |
| return loop; |
| } |
| |
| bool ExynosCamera::m_mainThreadFunc(void) |
| { |
| int ret = 0; |
| int index = 0; |
| ExynosCameraFrame *newFrame = NULL; |
| uint32_t frameCnt = 0; |
| |
| if (m_previewEnabled == false) { |
| CLOGD("DEBUG(%s):preview is stopped, thread stop", __FUNCTION__); |
| return false; |
| } |
| |
| ret = m_pipeFrameDoneQ->waitAndPopProcessQ(&newFrame); |
| if (m_flagThreadStop == true) { |
| CLOGI("INFO(%s[%d]):m_flagThreadStop(%d)", __FUNCTION__, __LINE__, m_flagThreadStop); |
| return false; |
| } |
| if (ret < 0) { |
| /* TODO: We need to make timeout duration depends on FPS */ |
| if (ret == TIMED_OUT) { |
| CLOGW("WARN(%s):wait timeout", __FUNCTION__); |
| } else { |
| CLOGE("ERR(%s):wait and pop fail, ret(%d)", __FUNCTION__, ret); |
| /* TODO: doing exception handling */ |
| } |
| return true; |
| } |
| |
| if (newFrame == NULL) { |
| CLOGE("ERR(%s[%d]):newFrame is NULL", __FUNCTION__, __LINE__); |
| return true; |
| } |
| |
| frameCnt = newFrame->getFrameCount(); |
| |
| /* HACK Reset Preview Flag*/ |
| #if 0 |
| if (m_exynosCameraParameters->getRestartPreview() == true) { |
| m_resetPreview = true; |
| ret = m_restartPreviewInternal(); |
| m_resetPreview = false; |
| CLOGE("INFO(%s[%d]) m_resetPreview(%d)", __FUNCTION__, __LINE__, m_resetPreview); |
| if (ret < 0) |
| CLOGE("(%s[%d]): restart preview internal fail", __FUNCTION__, __LINE__); |
| |
| return true; |
| } |
| #endif |
| |
| if (m_exynosCameraParameters->isFlite3aaOtf() == true) { |
| ret = m_handlePreviewFrame(newFrame); |
| } else { |
| if (m_exynosCameraParameters->getDualMode()) |
| ret = m_handlePreviewFrameFrontDual(newFrame); |
| else |
| ret = m_handlePreviewFrameFront(newFrame); |
| } |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):handle preview frame fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| /* Below code block is moved to m_handlePreviewFrame() and m_handlePreviewFrameFront() functions |
| * because we want to delete the frame as soon as the setFrameState(FRAME_STATE_COMPLETE) is called. |
| * Otherwise, some other thread might be executed between "setFrameState(FRAME_STATE_COMPLETE)" and |
| * "delete frame" statements and might delete the same frame. This would cause the second "delete frame" |
| * (trying to delete the same frame) to behave abnormally since that frame is already deleted. |
| */ |
| #if 0 |
| /* Don't use this lock */ |
| m_frameFliteDeleteBetweenPreviewReprocessing.lock(); |
| if (newFrame->isComplete() == true) { |
| ret = m_removeFrameFromList(&m_processList, newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):remove frame from processList fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| |
| if (newFrame->getFrameLockState() == false) |
| { |
| delete newFrame; |
| newFrame = NULL; |
| } |
| } |
| m_frameFliteDeleteBetweenPreviewReprocessing.unlock(); |
| #endif |
| |
| |
| /* |
| * HACK |
| * By using MCpipe. we don't use seperated pipe_scc. |
| * so, we will not meet inputFrameQ's fail issue. |
| */ |
| /* m_checkFpsAndUpdatePipeWaitTime(); */ |
| |
| if(getCameraId() == CAMERA_ID_BACK) { |
| m_autoFocusContinousQ.pushProcessQ(&frameCnt); |
| } |
| |
| return true; |
| } |
| |
| status_t ExynosCamera::m_handlePreviewFrame(ExynosCameraFrame *frame) |
| { |
| int ret = 0; |
| ExynosCameraFrameEntity *entity = NULL; |
| ExynosCameraFrameEntity *curentity = NULL; |
| ExynosCameraFrame *newFrame = NULL; |
| ExynosCameraFrame *fdFrame = NULL; |
| |
| ExynosCameraBuffer buffer; |
| |
| ExynosCameraBuffer t3acBuffer; |
| int pipeID = 0; |
| int dummyPipeId = -1; |
| /* to handle the high speed frame rate */ |
| bool skipPreview = false; |
| int ratio = 1; |
| uint32_t minFps = 0, maxFps = 0; |
| uint32_t dispFps = EXYNOS_CAMERA_PREVIEW_FPS_REFERENCE; |
| uint32_t fvalid = 0; |
| uint32_t fcount = 0; |
| uint32_t skipCount = 0; |
| struct camera2_stream *shot_stream = NULL; |
| ExynosCameraBuffer resultBuffer; |
| camera2_node_group node_group_info_isp; |
| int32_t reprocessingBayerMode = m_exynosCameraParameters->getReprocessingBayerMode(); |
| int ispDstBufferIndex = -1; |
| #ifdef SAMSUNG_LBP |
| unsigned int LBPframeCount = 0; |
| #endif |
| |
| entity = frame->getFrameDoneFirstEntity(); |
| if (entity == NULL) { |
| CLOGE("ERR(%s[%d]):current entity is NULL", __FUNCTION__, __LINE__); |
| /* TODO: doing exception handling */ |
| return true; |
| } |
| |
| curentity = entity; |
| pipeID = entity->getPipeId(); |
| |
| /* TODO: remove hard coding */ |
| switch(INDEX(entity->getPipeId())) { |
| case PIPE_3AA_ISP: |
| m_debugFpsCheck(entity->getPipeId()); |
| ret = frame->getSrcBuffer(entity->getPipeId(), &buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getSrcBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| return ret; |
| } |
| ret = m_putBuffers(m_3aaBufferMgr, buffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):put Buffer fail", __FUNCTION__, __LINE__); |
| } |
| |
| CLOGV("DEBUG(%s[%d]):3AA_ISP frameCount(%d) frame.Count(%d)", |
| __FUNCTION__, __LINE__, |
| getMetaDmRequestFrameCount((struct camera2_shot_ext *)buffer.addr[1]), |
| frame->getFrameCount()); |
| |
| ret = frame->getDstBuffer(entity->getPipeId(), &buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| return ret; |
| } |
| |
| ret = m_putBuffers(m_ispBufferMgr, buffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):put Buffer fail", __FUNCTION__, __LINE__); |
| break; |
| } |
| |
| frame->setMetaDataEnable(true); |
| |
| /* Face detection */ |
| if(!m_exynosCameraParameters->getHighSpeedRecording()) { |
| skipCount = m_exynosCameraParameters->getFrameSkipCount(); |
| if( m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA) && |
| skipCount <= 0) { |
| fdFrame = m_frameMgr->createFrame(m_exynosCameraParameters, frame->getFrameCount()); |
| m_copyMetaFrameToFrame(frame, fdFrame, true, true); |
| m_facedetectQ->pushProcessQ(&fdFrame); |
| } |
| } |
| |
| /* ISP capture mode q/dq for vdis */ |
| if (m_exynosCameraParameters->getTpuEnabledMode() == true) { |
| #if 0 |
| /* case 1 : directly push on isp, tpu. */ |
| ret = m_pushFrameToPipeIspDIS(); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):m_pushFrameToPipeIspDIS() fail", __FUNCTION__, __LINE__); |
| } |
| #else |
| /* case 2 : indirectly push on isp, tpu. */ |
| newFrame = m_frameMgr->createFrame(m_exynosCameraParameters, 0); |
| m_mainSetupQ[INDEX(PIPE_ISP)]->pushProcessQ(&newFrame); |
| #endif |
| } |
| |
| newFrame = m_frameMgr->createFrame(m_exynosCameraParameters, 0); |
| m_mainSetupQ[INDEX(entity->getPipeId())]->pushProcessQ(&newFrame); |
| break; |
| case PIPE_3AA: |
| m_debugFpsCheck(entity->getPipeId()); |
| |
| /* |
| if (entity->getSrcBufState() == ENTITY_BUFFER_STATE_ERROR) |
| m_previewFrameFactory->dump(); |
| */ |
| |
| /* 3AP buffer handling */ |
| ret = frame->getSrcBuffer(entity->getPipeId(), &buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getSrcBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| return ret; |
| } |
| |
| if (buffer.index >= 0) { |
| ret = m_putBuffers(m_3aaBufferMgr, buffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):put Buffer fail", __FUNCTION__, __LINE__); |
| } |
| } |
| |
| frame->setMetaDataEnable(true); |
| |
| /* 3AC buffer handling */ |
| do { |
| t3acBuffer.index = -1; |
| |
| if (frame->getRequest(PIPE_3AC) == true) { |
| ret = frame->getDstBuffer(entity->getPipeId(), &t3acBuffer, m_previewFrameFactory->getNodeType(PIPE_3AC)); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):getSrcBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| } |
| } |
| |
| if (0 <= t3acBuffer.index) { |
| if (frame->getRequest(PIPE_3AC) == true) { |
| if (m_exynosCameraParameters->getHighSpeedRecording() == true) { |
| ret = m_putBuffers(m_bayerBufferMgr, t3acBuffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_putBuffers(m_bayerBufferMgr, %d) fail", __FUNCTION__, __LINE__, t3acBuffer.index); |
| break; |
| } |
| } else { |
| entity_buffer_state_t bufferstate = ENTITY_BUFFER_STATE_NOREQ; |
| ret = frame->getDstBufferState(entity->getPipeId(), &bufferstate, m_previewFrameFactory->getNodeType(PIPE_3AC)); |
| if (ret == NO_ERROR && bufferstate != ENTITY_BUFFER_STATE_ERROR) { |
| ret = m_captureSelector->manageFrameHoldList(frame, entity->getPipeId(), false); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):manageFrameHoldList fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| } else { |
| ret = m_putBuffers(m_bayerBufferMgr, t3acBuffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_putBuffers(m_bayerBufferMgr, %d) fail", __FUNCTION__, __LINE__, t3acBuffer.index); |
| break; |
| } |
| } |
| } |
| } else { |
| if (reprocessingBayerMode == REPROCESSING_BAYER_MODE_DIRTY_ALWAYS_ON) { |
| CLOGW("WARN(%s[%d]):frame->getRequest(PIPE_3AC) == false. so, just m_putBuffers(t3acBuffer.index(%d)..., pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, t3acBuffer.index, entity->getPipeId(), ret); |
| } |
| |
| ret = m_putBuffers(m_bayerBufferMgr, t3acBuffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_putBuffers(m_bayerBufferMgr, %d) fail", __FUNCTION__, __LINE__, t3acBuffer.index); |
| break; |
| } |
| } |
| } |
| } while (0); |
| |
| CLOGV("DEBUG(%s[%d]):3AA_ISP frameCount(%d) frame.Count(%d)", |
| __FUNCTION__, __LINE__, |
| getMetaDmRequestFrameCount((struct camera2_shot_ext *)buffer.addr[1]), |
| frame->getFrameCount()); |
| |
| /* make the next (n + 1) frame */ |
| newFrame = m_frameMgr->createFrame(m_exynosCameraParameters, 0); |
| m_mainSetupQ[INDEX(entity->getPipeId())]->pushProcessQ(&newFrame); |
| |
| break; |
| case PIPE_3AC: |
| case PIPE_FLITE: |
| m_debugFpsCheck(entity->getPipeId()); |
| |
| #ifdef SAMSUNG_DNG |
| if (m_exynosCameraParameters->getUseDNGCapture()) { |
| CLOGV("[DNG](%s[%d]):PIPE_FLITE (%d)", __FUNCTION__, __LINE__, entity->getPipeId()); |
| |
| ret = frame->getDstBuffer(entity->getPipeId(), &buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| return ret; |
| } |
| |
| unsigned int fliteFcount = 0; |
| |
| /* Rawdump capture is available in pure bayer only */ |
| camera2_shot_ext *shot_ext = NULL; |
| shot_ext = (camera2_shot_ext *)(buffer.addr[1]); |
| if (shot_ext != NULL) |
| fliteFcount = shot_ext->shot.dm.request.frameCount; |
| else |
| ALOGE("ERR(%s[%d]):fliteReprocessingBuffer is null", __FUNCTION__, __LINE__); |
| |
| CLOGV("[DNG](%s[%d]):frame count (%d)", __FUNCTION__, __LINE__, fliteFcount); |
| |
| if (m_exynosCameraParameters->getCheckMultiFrame()) { |
| if (m_searchDNGFrame) { |
| unsigned int DNGFcount = 0; |
| bool DNGCapture_activated = false; |
| |
| if (getDNGFcount() != 0) { |
| m_dngFrameNumber = DNGFcount = getDNGFcount(); |
| } |
| |
| CLOGD("[DNG](%s[%d]):DNGFcount(%d) ois mode(%d) frame count(%d)", |
| __FUNCTION__, __LINE__,DNGFcount, m_exynosCameraParameters->getOISCaptureModeOn(), fliteFcount); |
| |
| if (DNGFcount > 0) { |
| DNGCapture_activated = true; |
| } |
| |
| if (m_exynosCameraParameters->getCaptureExposureTime() == 0 && |
| DNGCapture_activated && fliteFcount >= DNGFcount) { |
| DNGCapture_activated = false; |
| m_searchDNGFrame = false; |
| m_previewFrameFactory->setRequestFLITE(false); |
| |
| CLOGD("[DNG](%s[%d]):Raw frame count (%d)", __FUNCTION__, __LINE__, fliteFcount); |
| |
| m_DNGCaptureThread->run(); |
| m_dngCaptureQ->pushProcessQ(&buffer); |
| } else if (m_exynosCameraParameters->getCaptureExposureTime() != 0 && |
| getDNGFcount() == 0) { |
| if (!m_DNGCaptureThread->isRunning()) { |
| m_DNGCaptureThread->run(); |
| } |
| m_dngCaptureQ->pushProcessQ(&buffer); |
| newFrame = m_frameMgr->createFrame(m_exynosCameraParameters, 0); |
| m_mainSetupQ[INDEX(entity->getPipeId())]->pushProcessQ(&newFrame); |
| } else if (m_exynosCameraParameters->getCaptureExposureTime() != 0 && |
| DNGCapture_activated && fliteFcount >= DNGFcount) { |
| if (m_longExposureEnds) { |
| DNGCapture_activated = false; |
| m_searchDNGFrame = false; |
| m_previewFrameFactory->setRequestFLITE(false); |
| CLOGE("[DNG](%s[%d]):flite qbuffer m_searchDNGFrame(%d)", |
| __FUNCTION__, __LINE__, m_searchDNGFrame ,fliteFcount); |
| ret = m_putBuffers(m_fliteBufferMgr, buffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_putBuffers(%d) fail", __FUNCTION__, __LINE__, buffer.index); |
| break; |
| } |
| } else { |
| newFrame = m_frameMgr->createFrame(m_exynosCameraParameters, 0); |
| m_mainSetupQ[INDEX(entity->getPipeId())]->pushProcessQ(&newFrame); |
| m_dngCaptureQ->pushProcessQ(&buffer); |
| } |
| if (!m_DNGCaptureThread->isRunning() && !m_longExposureEnds) { |
| m_DNGCaptureThread->run(); |
| } |
| } else { |
| CLOGE("[DNG](%s[%d]):flite qbuffer m_searchDNGFrame(%d)", |
| __FUNCTION__, __LINE__, m_searchDNGFrame ,fliteFcount); |
| ret = m_putBuffers(m_fliteBufferMgr, buffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_putBuffers(%d) fail", __FUNCTION__, __LINE__, buffer.index); |
| break; |
| } |
| |
| newFrame = m_frameMgr->createFrame(m_exynosCameraParameters, 0); |
| m_mainSetupQ[INDEX(entity->getPipeId())]->pushProcessQ(&newFrame); |
| } |
| } else { |
| CLOGE("[DNG](%s[%d]):flite dqbuffer m_searchDNGFrame(%d)", |
| __FUNCTION__, __LINE__, m_searchDNGFrame ,fliteFcount); |
| ret = m_putBuffers(m_fliteBufferMgr, buffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_putBuffers(%d) fail", __FUNCTION__, __LINE__, buffer.index); |
| break; |
| } |
| } |
| } else { |
| CLOGD("[DNG](%s[%d]):Raw frame count (%d)", __FUNCTION__, __LINE__, fliteFcount); |
| m_dngFrameNumber = fliteFcount; |
| m_captureSelector->setDNGFrame(fliteFcount); |
| m_previewFrameFactory->stopThread(entity->getPipeId()); |
| m_DNGCaptureThread->run(); |
| m_dngCaptureQ->pushProcessQ(&buffer); |
| } |
| } else |
| #endif |
| { |
| if (m_exynosCameraParameters->getHighSpeedRecording()) { |
| ret = frame->getDstBuffer(entity->getPipeId(), &buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| return ret; |
| } |
| ret = m_putBuffers(m_bayerBufferMgr, buffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):put Buffer fail", __FUNCTION__, __LINE__); |
| break; |
| } |
| } else { |
| if (frame->getSccDrop() == true || frame->getIspcDrop() == true) { |
| CLOGE("ERR(%s[%d]):getSccDrop() == %d || getIspcDrop()== %d. so drop this frame(frameCount : %d)", |
| __FUNCTION__, __LINE__, frame->getSccDrop(), frame->getIspcDrop(), frame->getFrameCount()); |
| |
| ret = frame->getDstBuffer(entity->getPipeId(), &buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| return ret; |
| } |
| |
| ret = m_putBuffers(m_bayerBufferMgr, buffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_putBuffers(%d) fail", __FUNCTION__, __LINE__, buffer.index); |
| break; |
| } |
| } else { |
| ret = m_captureSelector->manageFrameHoldList(frame, entity->getPipeId(), false); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):manageFrameHoldList fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| } |
| } |
| |
| /* TODO: Dynamic bayer capture, currently support only single shot */ |
| if (reprocessingBayerMode == REPROCESSING_BAYER_MODE_PURE_DYNAMIC |
| || reprocessingBayerMode == REPROCESSING_BAYER_MODE_DIRTY_DYNAMIC) |
| m_previewFrameFactory->stopThread(entity->getPipeId()); |
| |
| if (reprocessingBayerMode == REPROCESSING_BAYER_MODE_PURE_ALWAYS_ON |
| || reprocessingBayerMode == REPROCESSING_BAYER_MODE_DIRTY_ALWAYS_ON) { |
| newFrame = m_frameMgr->createFrame(m_exynosCameraParameters, 0); |
| m_mainSetupQ[INDEX(entity->getPipeId())]->pushProcessQ(&newFrame); |
| } |
| } |
| break; |
| case PIPE_ISP: |
| /* |
| if (entity->getSrcBufState() == ENTITY_BUFFER_STATE_ERROR) |
| m_previewFrameFactory->dump(); |
| */ |
| |
| ret = frame->getSrcBuffer(entity->getPipeId(), &buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getSrcBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| return ret; |
| } |
| |
| if (buffer.index >= 0) { |
| ret = m_putBuffers(m_ispBufferMgr, buffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):put Buffer fail", __FUNCTION__, __LINE__); |
| break; |
| } |
| } |
| |
| /* ISP capture mode q/dq for vdis */ |
| if (m_exynosCameraParameters->getTpuEnabledMode() == true) { |
| break; |
| } |
| case PIPE_DIS: |
| /* this check twice on PIPE_SCP. so, disable */ |
| /* m_debugFpsCheck(pipeID); */ |
| if (m_exynosCameraParameters->getTpuEnabledMode() == true) { |
| ret = frame->getSrcBuffer(PIPE_DIS, &buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getSrcBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, PIPE_ISP, ret); |
| return ret; |
| } |
| |
| if (buffer.index >= 0) { |
| ret = m_putBuffers(m_hwDisBufferMgr, buffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_putBuffers(m_hwDisBufferMgr, %d) fail", |
| __FUNCTION__, __LINE__, buffer.index); |
| } |
| } |
| } |
| |
| CLOGV("DEBUG(%s[%d]):DIS done HAL-frameCount(%d)", |
| __FUNCTION__, __LINE__, frame->getFrameCount()); |
| |
| /* |
| * dis capture is scp. |
| * so, skip break; |
| */ |
| |
| case PIPE_SCP: |
| /* Face detection */ |
| if (!m_exynosCameraParameters->getHighSpeedRecording() |
| && frame->getFrameState() != FRAME_STATE_SKIPPED) { |
| skipCount = m_exynosCameraParameters->getFrameSkipCount(); |
| #ifdef SR_CAPTURE |
| if(m_isCopySrMdeta) { |
| frame->getDynamicMeta(&m_srShotMeta); |
| m_isCopySrMdeta = false; |
| CLOGI("INFO(%s[%d]) copy SR FdMeta", __FUNCTION__, __LINE__); |
| } |
| #endif |
| if( m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA) && |
| skipCount <= 0) { |
| fdFrame = m_frameMgr->createFrame(m_exynosCameraParameters, frame->getFrameCount()); |
| m_copyMetaFrameToFrame(frame, fdFrame, true, true); |
| m_facedetectQ->pushProcessQ(&fdFrame); |
| } |
| } |
| |
| if (m_exynosCameraParameters->getZoomPreviewWIthScaler()== true) { |
| CLOGV("INFO(%s[%d]): zoom preview with csc pipeId(%d) frame(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), frame->getFrameCount()); |
| |
| m_zoomPreviwWithCscQ->pushProcessQ(&frame); |
| break; |
| } else { |
| CLOGV("INFO(%s[%d]): zoom preview without csc pipeId(%d) frame(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), frame->getFrameCount()); |
| } |
| |
| case PIPE_GSC: |
| if (m_exynosCameraParameters->getZoomPreviewWIthScaler()== true) { |
| CLOGV("INFO(%s[%d]): zoom preview with csc pipeId(%d) frame(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), frame->getFrameCount()); |
| |
| dummyPipeId = (m_exynosCameraParameters->getTpuEnabledMode())? PIPE_DIS : PIPE_ISP; |
| ret = m_syncPrviewWithCSC(dummyPipeId, PIPE_GSC, frame); |
| if (ret < 0) { |
| CLOGW("WARN(%s[%d]):m_syncPrviewWithCSC failed frame(%d)", |
| __FUNCTION__, __LINE__, frame->getFrameCount()); |
| } |
| |
| entity = frame->searchEntityByPipeId(dummyPipeId); |
| if (entity == NULL) { |
| CLOGE("ERR(%s[%d]):searchEntityByPipeId failed pipe(%d) frame(%d)", |
| __FUNCTION__, __LINE__, dummyPipeId, frame->getFrameCount()); |
| } |
| } else { |
| CLOGV("INFO(%s[%d]): zoom preview without csc pipeId(%d) frame(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), frame->getFrameCount()); |
| } |
| |
| if (entity->getDstBufState() == ENTITY_BUFFER_STATE_ERROR) { |
| if (frame->getFrameState() != FRAME_STATE_SKIPPED) { |
| ret = frame->getDstBuffer(entity->getPipeId(), &buffer, m_previewFrameFactory->getNodeType(PIPE_SCP)); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| return ret; |
| } |
| |
| if (buffer.index >= 0) { |
| ret = m_scpBufferMgr->cancelBuffer(buffer.index, true); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):SCP buffer return fail", __FUNCTION__, __LINE__); |
| } |
| /* For debug */ |
| /* m_previewFrameFactory->dump(); */ |
| |
| /* Comment out, because it included ISP */ |
| /* |
| newFrame = m_previewFrameFactory->createNewFrameOnlyOnePipe(PIPE_SCP, frame->getFrameCount()); |
| newFrame->setDstBuffer(PIPE_SCP, buffer); |
| newFrame->setFrameState(FRAME_STATE_SKIPPED); |
| |
| m_mainSetupQ[INDEX(entity->getPipeId())]->pushProcessQ(&newFrame); |
| */ |
| } |
| CLOGV("DEBUG(%s[%d]):SCP done HAL-frameCount(%d)", __FUNCTION__, __LINE__, frame->getFrameCount()); |
| } else if (entity->getDstBufState() == ENTITY_BUFFER_STATE_COMPLETE) { |
| m_debugFpsCheck(entity->getPipeId()); |
| |
| ret = frame->getDstBuffer(entity->getPipeId(), &buffer, m_previewFrameFactory->getNodeType(PIPE_SCP)); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| return ret; |
| } |
| |
| memset(m_meta_shot, 0x00, sizeof(struct camera2_shot_ext)); |
| frame->getDynamicMeta(m_meta_shot); |
| frame->getUserDynamicMeta(m_meta_shot); |
| |
| m_checkEntranceLux(m_meta_shot); |
| #ifdef SAMSUNG_LBP |
| if (m_exynosCameraParameters->getUsePureBayerReprocessing() == true) { |
| camera2_shot_ext *shot_ext = NULL; |
| shot_ext = (camera2_shot_ext *)(buffer.addr[1]); |
| |
| if (shot_ext != NULL) |
| LBPframeCount = shot_ext->shot.dm.request.frameCount; |
| else |
| ALOGE("ERR(%s[%d]):Buffer is null", __FUNCTION__, __LINE__); |
| } else { |
| camera2_stream *lbp_shot_stream = NULL; |
| lbp_shot_stream = (struct camera2_stream *)buffer.addr[2]; |
| getStreamFrameCount(lbp_shot_stream, &LBPframeCount); |
| } |
| if(getCameraId() == CAMERA_ID_FRONT) |
| m_exynosCameraParameters->setSCPFrameCount(LBPframeCount); |
| #endif |
| #ifdef SAMSUNG_JQ |
| if(m_isJpegQtableOn == true |
| #ifdef SAMSUNG_LBP |
| && m_isLBPon == false |
| #endif |
| ) { |
| m_isJpegQtableOn = false; |
| ret = m_processJpegQtable(&buffer); |
| if (ret < 0) { |
| CLOGE("[JQ](%s[%d]): m_processJpegQtable() failed!!", __FUNCTION__, __LINE__); |
| } |
| } |
| #endif |
| #ifdef SAMSUNG_LLV |
| if (m_LLVstatus == LLV_INIT) { |
| int HwPreviewW = 0, HwPreviewH = 0; |
| m_exynosCameraParameters->getHwPreviewSize(&HwPreviewW, &HwPreviewH); |
| UniPluginBufferData_t pluginData; |
| memset(&pluginData, 0, sizeof(UniPluginBufferData_t)); |
| int powerCtrl = UNI_PLUGIN_POWER_CONTROL_OFF; |
| float Low_Lux = -5.5; |
| float High_Lux = -3.5; |
| float Low_Lux_Front = -5.2; |
| float High_Lux_Front = -3.2; |
| float LLV_Lux = (int32_t)m_meta_shot->shot.udm.ae.vendorSpecific[5] / 256.0; |
| |
| pluginData.InBuffY = buffer.addr[0]; |
| pluginData.InBuffU = buffer.addr[1]; |
| |
| pluginData.InWidth = HwPreviewW; |
| pluginData.InHeight = HwPreviewH; |
| pluginData.BrightnessLux = (int32_t)m_meta_shot->shot.udm.ae.vendorSpecific[5]; |
| |
| if (getCameraId() == CAMERA_ID_FRONT) { |
| if ((LLV_Lux > Low_Lux_Front) && (LLV_Lux <= High_Lux_Front)) |
| powerCtrl = UNI_PLUGIN_POWER_CONTROL_4; |
| } |
| else if (getCameraId() == CAMERA_ID_BACK){ |
| if ((LLV_Lux > Low_Lux) && (LLV_Lux <= High_Lux)) |
| powerCtrl = UNI_PLUGIN_POWER_CONTROL_4; |
| } |
| |
| #ifdef SAMSUNG_LLV_TUNING |
| powerCtrl = m_LLVpowerLevel; |
| CLOGD("[LLV_TEST] powerCtrl: %d", powerCtrl); |
| #endif |
| if(m_LLVpluginHandle != NULL) { |
| uni_plugin_set(m_LLVpluginHandle, |
| LLV_PLUGIN_NAME, UNI_PLUGIN_INDEX_BUFFER_INFO, &pluginData); |
| uni_plugin_set(m_LLVpluginHandle, |
| LLV_PLUGIN_NAME, UNI_PLUGIN_INDEX_POWER_CONTROL, &powerCtrl); |
| uni_plugin_process(m_LLVpluginHandle); |
| } |
| } |
| else if (m_LLVstatus == LLV_STOPPED) { |
| if(m_LLVpluginHandle != NULL) { |
| uni_plugin_deinit(m_LLVpluginHandle); |
| } |
| m_LLVstatus = LLV_UNINIT; |
| } |
| #endif |
| |
| #ifdef SAMSUNG_OT |
| if (m_exynosCameraParameters->getObjectTrackingChanged() == true |
| && m_OTstatus == UNI_PLUGIN_OBJECT_TRACKING_IDLE && m_OTstart == OBJECT_TRACKING_INIT) { |
| int maxNumFocusAreas = m_exynosCameraParameters->getMaxNumFocusAreas(); |
| ExynosRect2* objectTrackingArea = new ExynosRect2[maxNumFocusAreas]; |
| int* objectTrackingWeight = new int[maxNumFocusAreas]; |
| int validNumber; |
| UniPluginFocusData_t focusData; |
| memset(&focusData, 0, sizeof(UniPluginFocusData_t)); |
| |
| m_exynosCameraParameters->getObjectTrackingAreas(&validNumber, objectTrackingArea, objectTrackingWeight); |
| |
| for (int i = 0; i < validNumber; i++) { |
| focusData.FocusROILeft = objectTrackingArea[i].x1; |
| focusData.FocusROIRight = objectTrackingArea[i].x2; |
| focusData.FocusROITop = objectTrackingArea[i].y1; |
| focusData.FocusROIBottom = objectTrackingArea[i].y2; |
| focusData.FocusWeight = objectTrackingWeight[i]; |
| ret = uni_plugin_set(m_OTpluginHandle, |
| OBJECT_TRACKING_PLUGIN_NAME, UNI_PLUGIN_INDEX_FOCUS_INFO, &focusData); |
| if(ret < 0) { |
| CLOGE("[OBTR](%s[%d]):Object Tracking plugin set focus info failed!!", __FUNCTION__, __LINE__); |
| } |
| } |
| |
| delete[] objectTrackingArea; |
| delete[] objectTrackingWeight; |
| |
| m_exynosCameraParameters->setObjectTrackingChanged(false); |
| m_OTisTouchAreaGet = true; |
| } |
| |
| if ((m_exynosCameraParameters->getObjectTrackingEnable() == true |
| || m_exynosCameraParameters->getObjectTrackingGet() == true) |
| && m_OTstart == OBJECT_TRACKING_INIT |
| && m_OTisTouchAreaGet == true) { |
| int HwPreviewW = 0, HwPreviewH = 0; |
| m_exynosCameraParameters->getHwPreviewSize(&HwPreviewW, &HwPreviewH); |
| |
| UniPluginBufferData_t bufferData; |
| memset(&bufferData, 0, sizeof(UniPluginBufferData_t)); |
| |
| bufferData.InBuffY = buffer.addr[0]; |
| bufferData.InBuffU = buffer.addr[1]; |
| |
| bufferData.InWidth = HwPreviewW; |
| bufferData.InHeight = HwPreviewH; |
| bufferData.InFormat = UNI_PLUGIN_FORMAT_NV21; |
| ret = uni_plugin_set(m_OTpluginHandle, |
| OBJECT_TRACKING_PLUGIN_NAME, UNI_PLUGIN_INDEX_BUFFER_INFO, &bufferData); |
| if(ret < 0) { |
| CLOGE("[OBTR](%s[%d]):Object Tracking plugin set buffer info failed!!", __FUNCTION__, __LINE__); |
| } |
| |
| ret = uni_plugin_process(m_OTpluginHandle); |
| if(ret < 0) { |
| CLOGE("[OBTR](%s[%d]):Object Tracking plugin process failed!!", __FUNCTION__, __LINE__); |
| } |
| |
| uni_plugin_get(m_OTpluginHandle, |
| OBJECT_TRACKING_PLUGIN_NAME, UNI_PLUGIN_INDEX_FOCUS_INFO, &m_OTfocusData); |
| CLOGV("[OBTR](%s[%d])Focus state: %d, x1: %d, x2: %d, y1: %d, y2: %d, weight: %d", |
| __FUNCTION__, __LINE__, m_OTfocusData.FocusState, |
| m_OTfocusData.FocusROILeft, m_OTfocusData.FocusROIRight, |
| m_OTfocusData.FocusROITop, m_OTfocusData.FocusROIBottom, m_OTfocusData.FocusWeight); |
| CLOGV("[OBTR](%s[%d])Wmove: %d, Hmove: %d, Wvel: %d, Hvel: %d", |
| __FUNCTION__, __LINE__, m_OTfocusData.W_Movement, m_OTfocusData.H_Movement, |
| m_OTfocusData.W_Velocity, m_OTfocusData.H_Velocity); |
| |
| if (m_exynosCameraParameters->getObjectTrackingEnable() == true && m_OTstart == OBJECT_TRACKING_INIT) { |
| m_exynosCameraParameters->setObjectTrackingGet(true); |
| } |
| |
| m_OTstatus = m_OTfocusData.FocusState; |
| |
| uni_plugin_get(m_OTpluginHandle, |
| OBJECT_TRACKING_PLUGIN_NAME, UNI_PLUGIN_INDEX_FOCUS_PREDICTED, &m_OTpredictedData); |
| CLOGV("[OBTR](%s[%d])Predicted state: %d, x1: %d, x2: %d, y1: %d, y2: %d, weight: %d", |
| __FUNCTION__, __LINE__, m_OTpredictedData.FocusState, |
| m_OTpredictedData.FocusROILeft, m_OTpredictedData.FocusROIRight, |
| m_OTpredictedData.FocusROITop, m_OTpredictedData.FocusROIBottom, m_OTpredictedData.FocusWeight); |
| CLOGV("[OBTR](%s[%d])Wmove: %d, Hmove: %d, Wvel: %d, Hvel: %d", |
| __FUNCTION__, __LINE__, m_OTpredictedData.W_Movement, m_OTpredictedData.H_Movement, |
| m_OTpredictedData.W_Velocity, m_OTpredictedData.H_Velocity); |
| |
| ExynosRect cropRegionRect; |
| ExynosRect2 oldrect, newRect; |
| oldrect.x1 = m_OTpredictedData.FocusROILeft; |
| oldrect.x2 = m_OTpredictedData.FocusROIRight; |
| oldrect.y1 = m_OTpredictedData.FocusROITop; |
| oldrect.y2 = m_OTpredictedData.FocusROIBottom; |
| m_exynosCameraParameters->getHwBayerCropRegion(&cropRegionRect.w, &cropRegionRect.h, &cropRegionRect.x, &cropRegionRect.y); |
| newRect = convertingAndroidArea2HWAreaBcropOut(&oldrect, &cropRegionRect); |
| m_OTpredictedData.FocusROILeft = newRect.x1; |
| m_OTpredictedData.FocusROIRight = newRect.x2; |
| m_OTpredictedData.FocusROITop = newRect.y1; |
| m_OTpredictedData.FocusROIBottom = newRect.y2; |
| |
| ExynosCameraActivityAutofocus *autoFocusMgr = m_exynosCameraActivityControl->getAutoFocusMgr(); |
| ret = autoFocusMgr->setObjectTrackingAreas(&m_OTpredictedData); |
| if(ret == false) { |
| CLOGE("[OBTR](%s[%d]):setObjectTrackingAreas failed!!", __FUNCTION__, __LINE__); |
| } |
| } |
| if(m_OTstart == OBJECT_TRACKING_DEINIT) { |
| int ret = uni_plugin_deinit(m_OTpluginHandle); |
| if(ret < 0) { |
| CLOGE("[OBTR](%s[%d]):Object Tracking plugin deinit failed!!", __FUNCTION__, __LINE__); |
| } |
| m_OTstart = OBJECT_TRACKING_IDLE; |
| /* Waiting in the recording mode can make preview thread stop */ |
| #if 0 |
| m_OT_mutex.lock(); |
| if(m_OTisWait == true) |
| m_OT_condition.signal(); |
| m_OT_mutex.unlock(); |
| #endif |
| } |
| #endif |
| #ifdef SAMSUNG_LBP |
| if(((m_captureSelector->getFrameIndex() == LBPframeCount && m_captureSelector->getFrameIndex()) |
| || (m_LBPindex > 0 && m_LBPindex < m_exynosCameraParameters->getHoldFrameCount())) |
| && m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_NONE |
| && m_isLBPon == true){ |
| CLOGD("[LBP](%s[%d]):Start BestPic(%d/%d)", __FUNCTION__, __LINE__, LBPframeCount, m_LBPindex); |
| char *srcAddr = NULL; |
| char *dstAddr = NULL; |
| int hwPreviewFormat = m_exynosCameraParameters->getHwPreviewFormat(); |
| int planeCount = getYuvPlaneCount(hwPreviewFormat); |
| if (planeCount <= 0) { |
| CLOGE("[LBP](%s[%d]):getYuvPlaneCount(%d) fail", __FUNCTION__, __LINE__, hwPreviewFormat); |
| } |
| |
| ret = m_lbpBufferMgr->getBuffer(&m_LBPindex, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL, &m_LBPbuffer[m_LBPindex].buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_lbpBufferMgr->getBuffer fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| return ret; |
| } |
| |
| /* TODO : have to consider all fmt(planes) and stride */ |
| for (int plane = 0; plane < planeCount; plane++) { |
| srcAddr = buffer.addr[plane]; |
| dstAddr = m_LBPbuffer[m_LBPindex].buffer.addr[plane]; |
| memcpy(dstAddr, srcAddr, m_LBPbuffer[m_LBPindex].buffer.size[plane]); |
| } |
| m_LBPbuffer[m_LBPindex].frameNumber = LBPframeCount; |
| /* There is a case that LBP thread ends first, we need to increase the index before that. */ |
| m_LBPindex++; |
| m_LBPbufferQ->pushProcessQ(&m_LBPbuffer[m_LBPindex-1]); |
| } |
| #endif |
| #ifdef SUPPORT_SW_VDIS |
| if(m_swVDIS_Mode) { |
| memset(m_swVDIS_fd_dm, 0x00, sizeof(struct camera2_dm)); |
| if (frame->getDynamicMeta(m_swVDIS_fd_dm) != NO_ERROR) { |
| CLOGE("ERR(%s[%d]) meta_shot_ext is null", __FUNCTION__, __LINE__); |
| } |
| |
| int swVDIS_BufIndex = -1; |
| int swVDIS_IndexCount = (m_swVDIS_FrameNum % NUM_VDIS_BUFFERS); |
| ret = m_swVDIS_BufferMgr->getBuffer(&swVDIS_BufIndex, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL, |
| &m_swVDIS_OutBuf[swVDIS_IndexCount]); |
| |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_swVDIS_BufferMgr->getBuffer fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| return ret; |
| } |
| |
| nsecs_t swVDIS_timeStamp = (nsecs_t)frame->getTimeStamp(); |
| nsecs_t swVDIS_timeStampBoot = (nsecs_t)frame->getTimeStampBoot(); |
| int swVDIS_Lux = m_meta_shot->shot.udm.ae.vendorSpecific[5] / 256; |
| int swVDIS_ZoomLevel = m_exynosCameraParameters->getZoomLevel(); |
| float swVDIS_ExposureValue = (int32_t)m_meta_shot->shot.udm.ae.vendorSpecific[4] / 256.0; |
| |
| int swVDIS_num = 0; |
| swVDIS_num = NUM_OF_DETECTED_FACES; |
| memset(m_swVDIS_FaceData, 0x00, sizeof(swVDIS_FaceData_t)); |
| |
| for (int i = 0; i < swVDIS_num; i++) { |
| if (m_swVDIS_fd_dm->stats.faceIds[i]) { |
| m_swVDIS_FaceData->FaceRect[i].left = m_swVDIS_fd_dm->stats.faceRectangles[i][0]; |
| m_swVDIS_FaceData->FaceRect[i].top = m_swVDIS_fd_dm->stats.faceRectangles[i][1]; |
| m_swVDIS_FaceData->FaceRect[i].right = m_swVDIS_fd_dm->stats.faceRectangles[i][2]; |
| m_swVDIS_FaceData->FaceRect[i].bottom= m_swVDIS_fd_dm->stats.faceRectangles[i][3]; |
| m_swVDIS_FaceData->FaceNum++; |
| } |
| } |
| |
| m_swVDIS_process(&buffer, swVDIS_IndexCount, swVDIS_timeStamp, swVDIS_timeStampBoot, |
| swVDIS_Lux, swVDIS_ZoomLevel, swVDIS_ExposureValue, m_swVDIS_FaceData); |
| |
| #ifdef SAMSUNG_OIS_VDIS |
| if(m_exynosCameraParameters->getOIS() == OPTICAL_STABILIZATION_MODE_VDIS) { |
| UNI_PLUGIN_OIS_MODE mode = m_swVDIS_getOISmode(); |
| uint32_t coef = 0; |
| if(mode == UNI_PLUGIN_OIS_MODE_CENTERING) |
| coef = 0xFFFF; |
| else |
| coef = 0x1; |
| |
| if(m_OISvdisMode != mode) { |
| CLOGD("DEBUG(%s[%d]):OIS VDIS coef: %d", __FUNCTION__, __LINE__, coef); |
| m_OISvdisMode = mode; |
| } |
| m_exynosCameraParameters->setOISCoef(coef); |
| } |
| #endif |
| } |
| #endif /*SUPPORT_SW_VDIS*/ |
| |
| /* TO DO : skip frame for HDR */ |
| shot_stream = (struct camera2_stream *)buffer.addr[2]; |
| |
| if (shot_stream != NULL) { |
| getStreamFrameValid(shot_stream, &fvalid); |
| getStreamFrameCount(shot_stream, &fcount); |
| } else { |
| CLOGE("ERR(%s[%d]):shot_stream is NULL", __FUNCTION__, __LINE__); |
| fvalid = false; |
| fcount = 0; |
| } |
| |
| /* drop preview frame if lcd supported frame rate < scp frame rate */ |
| frame->getFpsRange(&minFps, &maxFps); |
| if (dispFps < maxFps) { |
| ratio = (int)((maxFps * 10 / dispFps) / 10); |
| m_displayPreviewToggle = (m_displayPreviewToggle + 1) % ratio; |
| skipPreview = (m_displayPreviewToggle == 0) ? true : false; |
| #ifdef DEBUG |
| CLOGE("DEBUG(%s[%d]):preview frame skip! frameCount(%d) (m_displayPreviewToggle=%d,\ |
| maxFps=%d, dispFps=%d, ratio=%d, skipPreview=%d)", |
| __FUNCTION__, __LINE__, frame->getFrameCount(), |
| m_displayPreviewToggle, maxFps, dispFps, ratio, (int)skipPreview); |
| #endif |
| } |
| |
| newFrame = m_previewFrameFactory->createNewFrameOnlyOnePipe(PIPE_SCP, frame->getFrameCount()); |
| |
| newFrame->setDstBuffer(PIPE_SCP, buffer); |
| |
| m_exynosCameraParameters->getFrameSkipCount(&m_frameSkipCount); |
| if (m_frameSkipCount > 0) { |
| CLOGD("INFO(%s[%d]):Skip frame for frameSkipCount(%d) buffer.index(%d)", |
| __FUNCTION__, __LINE__, m_frameSkipCount, buffer.index); |
| #ifdef SUPPORT_SW_VDIS |
| if(m_swVDIS_Mode) { |
| if(m_frameSkipCount == 1) { |
| for(int i = 0; i < NUM_VDIS_BUFFERS; i++) { |
| ret = m_swVDIS_BufferMgr->cancelBuffer(i); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):swVDIS buffer return fail", __FUNCTION__, __LINE__); |
| } |
| } |
| } |
| } |
| #endif /*SUPPORT_SW_VDIS*/ |
| newFrame->setFrameState(FRAME_STATE_SKIPPED); |
| if (buffer.index >= 0) { |
| ret = m_scpBufferMgr->cancelBuffer(buffer.index, true); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):SCP buffer return fail", __FUNCTION__, __LINE__); |
| } |
| |
| } else { |
| if (m_skipReprocessing == true) |
| m_skipReprocessing = false; |
| #ifdef SUPPORT_SW_VDIS |
| if(m_swVDIS_Mode) { |
| nsecs_t timeStamp = m_swVDIS_timeStamp[m_swVDIS_OutBuf[m_swVDIS_OutQIndex].index]; |
| |
| ret = m_putBuffers(m_swVDIS_BufferMgr, m_swVDIS_OutBuf[m_swVDIS_OutQIndex].index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):put Buffer fail", __FUNCTION__, __LINE__); |
| break; |
| } |
| |
| if (m_getRecordingEnabled() == true |
| && m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_VIDEO_FRAME)) { |
| if (timeStamp <= 0L) { |
| CLOGE("WARN(%s[%d]):timeStamp(%lld) Skip", __FUNCTION__, __LINE__, timeStamp); |
| } else { |
| if (m_exynosCameraParameters->doCscRecording() == true) { |
| /* get Recording Image buffer */ |
| int bufIndex = -2; |
| ExynosCameraBuffer recordingBuffer; |
| ret = m_recordingBufferMgr->getBuffer(&bufIndex, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL, &recordingBuffer); |
| if (ret < 0 || bufIndex < 0) { |
| if ((++m_recordingFrameSkipCount % 100) == 0) { |
| CLOGE("ERR(%s[%d]): Recording buffer is not available!! Recording Frames are Skipping(%d frames) (bufIndex=%d)", |
| __FUNCTION__, __LINE__, m_recordingFrameSkipCount, bufIndex); |
| m_recordingBufferMgr->printBufferQState(); |
| } |
| } else { |
| if (m_recordingFrameSkipCount != 0) { |
| CLOGE("ERR(%s[%d]): Recording buffer is not available!! Recording Frames are Skipped(%d frames) (bufIndex=%d) (recordingQ=%d)", |
| __FUNCTION__, __LINE__, m_recordingFrameSkipCount, bufIndex, m_recordingQ->getSizeOfProcessQ()); |
| m_recordingFrameSkipCount = 0; |
| m_recordingBufferMgr->printBufferQState(); |
| } |
| |
| ret = m_doPrviewToRecordingFunc(PIPE_GSC_VIDEO, m_swVDIS_OutBuf[m_swVDIS_OutQIndex], recordingBuffer, timeStamp); |
| if (ret < 0) { |
| CLOGW("WARN(%s[%d]):recordingCallback Skip", __FUNCTION__, __LINE__); |
| } |
| } |
| } else { |
| m_recordingTimeStamp[m_swVDIS_OutBuf[m_swVDIS_OutQIndex].index] = timeStamp; |
| |
| if (m_recordingStartTimeStamp == 0) { |
| m_recordingStartTimeStamp = timeStamp; |
| CLOGI("INFO(%s[%d]):m_recordingStartTimeStamp=%lld", |
| __FUNCTION__, __LINE__, m_recordingStartTimeStamp); |
| } |
| |
| if ((0L < timeStamp) |
| && (m_lastRecordingTimeStamp < timeStamp) |
| && (m_recordingStartTimeStamp <= timeStamp)) { |
| if (m_getRecordingEnabled() == true |
| && m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_VIDEO_FRAME)) { |
| #ifdef CHECK_MONOTONIC_TIMESTAMP |
| CLOGD("DEBUG(%s[%d]):m_dataCbTimestamp::recordingFrameIndex=%d, recordingTimeStamp=%lld, fd[0]=%d", |
| __FUNCTION__, __LINE__, m_swVDIS_OutBuf[m_swVDIS_OutQIndex].index, timeStamp, m_swVDIS_OutBuf[m_swVDIS_OutQIndex].fd[0]); |
| #endif |
| #ifdef DEBUG |
| CLOGD("DEBUG(%s[%d]): - lastTimeStamp(%lld), systemTime(%lld), recordingStart(%lld)", |
| __FUNCTION__, __LINE__, |
| m_lastRecordingTimeStamp, |
| systemTime(SYSTEM_TIME_MONOTONIC), |
| m_recordingStartTimeStamp); |
| #endif |
| |
| if (m_recordingBufAvailable[m_swVDIS_OutBuf[m_swVDIS_OutQIndex].index] == false) { |
| CLOGW("WARN(%s[%d]):recordingFrameIndex(%d) didn't release yet !!! drop the frame !!! " |
| " timeStamp(%lld) m_recordingBufAvailable(%d)", |
| __FUNCTION__, |
| __LINE__, |
| m_swVDIS_OutBuf[m_swVDIS_OutQIndex].index, |
| timeStamp, |
| (int)m_recordingBufAvailable[m_swVDIS_OutBuf[m_swVDIS_OutQIndex].index]); |
| } else { |
| if (m_recordingCallbackHeap != NULL) { |
| |
| struct VideoNativeHandleMetadata *recordAddrs = NULL; |
| |
| recordAddrs = (struct VideoNativeHandleMetadata *)m_recordingCallbackHeap->data; |
| recordAddrs[m_swVDIS_OutBuf[m_swVDIS_OutQIndex].index].eType = kMetadataBufferTypeNativeHandleSource; |
| |
| native_handle* handle = native_handle_create(2, 1); |
| handle->data[0] = (int32_t) m_swVDIS_OutBuf[m_swVDIS_OutQIndex].fd[0]; |
| handle->data[1] = (int32_t) m_swVDIS_OutBuf[m_swVDIS_OutQIndex].fd[1]; |
| handle->data[2] = (int32_t) m_swVDIS_OutBuf[m_swVDIS_OutQIndex].index; |
| |
| recordAddrs[m_swVDIS_OutBuf[m_swVDIS_OutQIndex].index].pHandle = handle; |
| |
| m_recordingBufAvailable[m_swVDIS_OutBuf[m_swVDIS_OutQIndex].index] = false; |
| m_lastRecordingTimeStamp = timeStamp; |
| } else { |
| CLOGD("INFO(%s[%d]) : m_recordingCallbackHeap is NULL.", __FUNCTION__, __LINE__); |
| } |
| |
| if (m_getRecordingEnabled() == true |
| && m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_VIDEO_FRAME)) { |
| #ifdef SAMSUNG_HLV |
| if (m_HLV) { |
| /* Ignore the ERROR .. HLV solution is smart */ |
| ret = m_ProgramAndProcessHLV(&m_swVDIS_OutBuf[m_swVDIS_OutQIndex]); |
| } |
| #endif |
| m_dataCbTimestamp( |
| timeStamp, |
| CAMERA_MSG_VIDEO_FRAME, |
| m_recordingCallbackHeap, |
| m_swVDIS_OutBuf[m_swVDIS_OutQIndex].index, |
| m_callbackCookie); |
| } |
| } |
| } |
| } else { |
| CLOGW("WARN(%s[%d]):recordingFrameIndex=%d, timeStamp(%lld) invalid -" |
| " lastTimeStamp(%lld), systemTime(%lld), recordingStart(%lld), m_recordingBufAvailable(%d)", |
| __FUNCTION__, __LINE__, m_swVDIS_OutBuf[m_swVDIS_OutQIndex].index, timeStamp, |
| m_lastRecordingTimeStamp, |
| systemTime(SYSTEM_TIME_MONOTONIC), |
| m_recordingStartTimeStamp, |
| (int)m_recordingBufAvailable[m_swVDIS_OutBuf[m_swVDIS_OutQIndex].index]); |
| m_recordingTimeStamp[m_swVDIS_OutBuf[m_swVDIS_OutQIndex].index] = 0L; |
| } |
| } |
| } |
| } |
| } |
| else |
| #endif /*SUPPORT_SW_VDIS*/ |
| { |
| nsecs_t timeStamp = (nsecs_t)frame->getTimeStamp(); |
| |
| if (m_getRecordingEnabled() == true |
| && m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_VIDEO_FRAME)) { |
| if (timeStamp <= 0L) { |
| CLOGE("WARN(%s[%d]):timeStamp(%lld) Skip", __FUNCTION__, __LINE__, (long long)timeStamp); |
| } else { |
| if (m_exynosCameraParameters->doCscRecording() == true) { |
| /* get Recording Image buffer */ |
| int bufIndex = -2; |
| ExynosCameraBuffer recordingBuffer; |
| ret = m_recordingBufferMgr->getBuffer(&bufIndex, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL, &recordingBuffer); |
| if (ret < 0 || bufIndex < 0) { |
| if ((++m_recordingFrameSkipCount % 100) == 0) { |
| CLOGE("ERR(%s[%d]): Recording buffer is not available!! Recording Frames are Skipping(%d frames) (bufIndex=%d)", |
| __FUNCTION__, __LINE__, m_recordingFrameSkipCount, bufIndex); |
| m_recordingBufferMgr->printBufferQState(); |
| } |
| } else { |
| if (m_recordingFrameSkipCount != 0) { |
| CLOGE("ERR(%s[%d]): Recording buffer is not available!! Recording Frames are Skipped(%d frames) (bufIndex=%d) (recordingQ=%d)", |
| __FUNCTION__, __LINE__, m_recordingFrameSkipCount, bufIndex, m_recordingQ->getSizeOfProcessQ()); |
| m_recordingFrameSkipCount = 0; |
| m_recordingBufferMgr->printBufferQState(); |
| } |
| |
| ret = m_doPrviewToRecordingFunc(PIPE_GSC_VIDEO, buffer, recordingBuffer, timeStamp); |
| if (ret < 0) { |
| CLOGW("WARN(%s[%d]):recordingCallback Skip", __FUNCTION__, __LINE__); |
| } |
| } |
| } else { |
| m_recordingTimeStamp[buffer.index] = timeStamp; |
| |
| if (m_recordingStartTimeStamp == 0) { |
| m_recordingStartTimeStamp = timeStamp; |
| CLOGI("INFO(%s[%d]):m_recordingStartTimeStamp=%lld", |
| __FUNCTION__, __LINE__, (long long)m_recordingStartTimeStamp); |
| } |
| |
| if ((0L < timeStamp) |
| && (m_lastRecordingTimeStamp < timeStamp) |
| && (m_recordingStartTimeStamp <= timeStamp)) { |
| if (m_getRecordingEnabled() == true |
| && m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_VIDEO_FRAME)) { |
| #ifdef CHECK_MONOTONIC_TIMESTAMP |
| CLOGD("DEBUG(%s[%d]):m_dataCbTimestamp::recordingFrameIndex=%d, recordingTimeStamp=%lld, fd[0]=%d", |
| __FUNCTION__, __LINE__, buffer.index, (long long)timeStamp, buffer.fd[0]); |
| #endif |
| #ifdef DEBUG |
| CLOGD("DEBUG(%s[%d]): - lastTimeStamp(%lld), systemTime(%lld), recordingStart(%lld)", |
| __FUNCTION__, __LINE__, |
| (long long)m_lastRecordingTimeStamp, |
| (long long)systemTime(SYSTEM_TIME_MONOTONIC), |
| (long long)m_recordingStartTimeStamp); |
| #endif |
| |
| if (m_recordingBufAvailable[buffer.index] == false) { |
| CLOGW("WARN(%s[%d]):recordingFrameIndex(%d) didn't release yet !!! drop the frame !!! " |
| " timeStamp(%lld) m_recordingBufAvailable(%d)", |
| __FUNCTION__, __LINE__, buffer.index, (long long)timeStamp, (int)m_recordingBufAvailable[buffer.index]); |
| } else { |
| if (m_recordingCallbackHeap != NULL) { |
| struct VideoNativeHandleMetadata *recordAddrs = NULL; |
| |
| recordAddrs = (struct VideoNativeHandleMetadata *)m_recordingCallbackHeap->data; |
| recordAddrs[buffer.index].eType = kMetadataBufferTypeNativeHandleSource; |
| |
| native_handle* handle = native_handle_create(2, 1); |
| handle->data[0] = (int32_t) buffer.fd[0]; |
| handle->data[1] = (int32_t) buffer.fd[1]; |
| handle->data[2] = (int32_t) buffer.index; |
| |
| recordAddrs[buffer.index].pHandle = handle; |
| |
| m_recordingBufAvailable[buffer.index] = false; |
| m_lastRecordingTimeStamp = timeStamp; |
| } else { |
| CLOGD("INFO(%s[%d]) : m_recordingCallbackHeap is NULL.", __FUNCTION__, __LINE__); |
| } |
| |
| if (m_getRecordingEnabled() == true |
| && m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_VIDEO_FRAME)) { |
| #ifdef SAMSUNG_HLV |
| if (m_HLV) { |
| /* Ignore the ERROR .. HLV solution is smart */ |
| ret = m_ProgramAndProcessHLV(&buffer); |
| } |
| #endif |
| m_dataCbTimestamp( |
| timeStamp, |
| CAMERA_MSG_VIDEO_FRAME, |
| m_recordingCallbackHeap, |
| buffer.index, |
| m_callbackCookie); |
| } |
| } |
| } |
| } else { |
| CLOGW("WARN(%s[%d]):recordingFrameIndex=%d, timeStamp(%lld) invalid -" |
| " lastTimeStamp(%lld), systemTime(%lld), recordingStart(%lld), m_recordingBufAvailable(%d)", |
| __FUNCTION__, __LINE__, buffer.index, (long long)timeStamp, |
| (long long)m_lastRecordingTimeStamp, |
| (long long)systemTime(SYSTEM_TIME_MONOTONIC), |
| (long long)m_recordingStartTimeStamp, |
| (int)m_recordingBufAvailable[buffer.index]); |
| m_recordingTimeStamp[buffer.index] = 0L; |
| } |
| } |
| } |
| } |
| } |
| |
| ExynosCameraBuffer callbackBuffer; |
| ExynosCameraFrame *callbackFrame = NULL; |
| |
| callbackFrame = m_previewFrameFactory->createNewFrameOnlyOnePipe(PIPE_SCP, frame->getFrameCount()); |
| frame->getDstBuffer(entity->getPipeId(), &callbackBuffer, m_previewFrameFactory->getNodeType(PIPE_SCP)); |
| m_copyMetaFrameToFrame(frame, callbackFrame, true, true); |
| |
| callbackFrame->setDstBuffer(PIPE_SCP, callbackBuffer); |
| |
| if (((m_exynosCameraParameters->getPreviewBufferCount() == NUM_PREVIEW_BUFFERS + NUM_PREVIEW_SPARE_BUFFERS && |
| m_previewQ->getSizeOfProcessQ() >= 2) || |
| (m_exynosCameraParameters->getPreviewBufferCount() == NUM_PREVIEW_BUFFERS && |
| m_previewQ->getSizeOfProcessQ() >= 1)) && |
| (m_previewThread->isRunning() == true)) { |
| |
| if ((m_getRecordingEnabled() == true) && (m_exynosCameraParameters->doCscRecording() == false)) { |
| CLOGW("WARN(%s[%d]):push frame to previewQ. PreviewQ(%d), PreviewBufferCount(%d)", |
| __FUNCTION__, |
| __LINE__, |
| m_previewQ->getSizeOfProcessQ(), |
| m_exynosCameraParameters->getPreviewBufferCount()); |
| m_previewQ->pushProcessQ(&callbackFrame); |
| } else { |
| CLOGW("WARN(%s[%d]):Frames are stacked in previewQ. Skip frame. PreviewQ(%d), PreviewBufferCount(%d)", |
| __FUNCTION__, __LINE__, |
| m_previewQ->getSizeOfProcessQ(), |
| m_exynosCameraParameters->getPreviewBufferCount()); |
| newFrame->setFrameState(FRAME_STATE_SKIPPED); |
| if (buffer.index >= 0) { |
| /* only apply in the Full OTF of Exynos74xx. */ |
| ret = m_scpBufferMgr->cancelBuffer(buffer.index, true); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):SCP buffer return fail", __FUNCTION__, __LINE__); |
| } |
| |
| callbackFrame->decRef(); |
| m_frameMgr->deleteFrame(callbackFrame); |
| callbackFrame = NULL; |
| } |
| |
| } else if((m_exynosCameraParameters->getFastFpsMode() > 1) && (m_exynosCameraParameters->getRecordingHint() == 1)) { |
| m_skipCount++; |
| #ifdef SAMSUNG_TN_FEATURE |
| short skipInterval = (m_exynosCameraParameters->getFastFpsMode() - 1) * 2; |
| |
| if((m_exynosCameraParameters->getShotMode() == SHOT_MODE_SEQUENCE && (m_skipCount%4 != 0)) |
| || (m_exynosCameraParameters->getShotMode() != SHOT_MODE_SEQUENCE && (m_skipCount % skipInterval) > 0)) { |
| CLOGV("INFO(%s[%d]):fast fps mode skip frame(%d) ", __FUNCTION__, __LINE__,m_skipCount); |
| newFrame->setFrameState(FRAME_STATE_SKIPPED); |
| if (buffer.index >= 0) { |
| /* only apply in the Full OTF of Exynos74xx. */ |
| ret = m_scpBufferMgr->cancelBuffer(buffer.index, true); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):SCP buffer return fail", __FUNCTION__, __LINE__); |
| } |
| |
| callbackFrame->decRef(); |
| m_frameMgr->deleteFrame(callbackFrame); |
| callbackFrame = NULL; |
| } else |
| #endif |
| { |
| CLOGV("INFO(%s[%d]):push frame to previewQ", __FUNCTION__, __LINE__); |
| m_previewQ->pushProcessQ(&callbackFrame); |
| } |
| } else { |
| if (m_getRecordingEnabled() == true) { |
| CLOGV("INFO(%s[%d]):push frame to previewQ", __FUNCTION__, __LINE__); |
| m_previewQ->pushProcessQ(&callbackFrame); |
| m_longExposurePreview = false; |
| } else if (m_exynosCameraParameters->getCaptureExposureTime() > 0 && |
| (m_meta_shot->shot.dm.sensor.exposureTime / 1000) > CAMERA_PREVIEW_EXPOSURE_TIME_LIMIT) { |
| CLOGD("INFO(%s[%d]):manual exposure capture mode. %lld", |
| __FUNCTION__, __LINE__, (long long)m_meta_shot->shot.dm.sensor.exposureTime); |
| newFrame->setFrameState(FRAME_STATE_SKIPPED); |
| if (buffer.index >= 0) { |
| /* only apply in the Full OTF of Exynos74xx. */ |
| ret = m_scpBufferMgr->cancelBuffer(buffer.index, true); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):SCP buffer return fail", __FUNCTION__, __LINE__); |
| } |
| |
| callbackFrame->decRef(); |
| m_frameMgr->deleteFrame(callbackFrame); |
| callbackFrame = NULL; |
| m_longExposurePreview = true; |
| } else { |
| #ifdef OIS_CAPTURE |
| ExynosCameraActivitySpecialCapture *m_sCaptureMgr = NULL; |
| unsigned int OISFcount = 0; |
| unsigned int fliteFcount = 0; |
| bool OISCapture_activated = false; |
| |
| m_sCaptureMgr = m_exynosCameraActivityControl->getSpecialCaptureMgr(); |
| OISFcount = m_sCaptureMgr->getOISCaptureFcount(); |
| OISFcount += OISCAPTURE_DELAY; |
| fliteFcount = m_meta_shot->shot.dm.request.frameCount; |
| |
| if(OISFcount > OISCAPTURE_DELAY) { |
| if (OISFcount == fliteFcount |
| #ifdef SAMSUNG_LLS_DEBLUR |
| && m_exynosCameraParameters->getLDCaptureMode() == MULTI_SHOT_MODE_NONE |
| #endif |
| ) { |
| OISCapture_activated = true; |
| } |
| #ifdef SAMSUNG_LLS_DEBLUR |
| else if (m_exynosCameraParameters->getLDCaptureMode() > MULTI_SHOT_MODE_NONE |
| && OISFcount <= fliteFcount |
| && fliteFcount < OISFcount + m_exynosCameraParameters->getLDCaptureCount()) { |
| OISCapture_activated = true; |
| } |
| #endif |
| } |
| |
| if((m_exynosCameraParameters->getSeriesShotCount() == 0 |
| #ifdef LLS_REPROCESSING |
| || m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_LLS |
| #endif |
| ) && OISCapture_activated) { |
| CLOGD("INFO(%s[%d]):OIS capture mode. Skip frame. FliteFrameCount(%d) ", __FUNCTION__, __LINE__,fliteFcount); |
| newFrame->setFrameState(FRAME_STATE_SKIPPED); |
| if (buffer.index >= 0) { |
| /* only apply in the Full OTF of Exynos74xx. */ |
| ret = m_scpBufferMgr->cancelBuffer(buffer.index, true); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):SCP buffer return fail", __FUNCTION__, __LINE__); |
| } |
| |
| callbackFrame->decRef(); |
| m_frameMgr->deleteFrame(callbackFrame); |
| callbackFrame = NULL; |
| } else |
| #endif |
| { |
| CLOGV("INFO(%s[%d]):push frame to previewQ", __FUNCTION__, __LINE__); |
| m_previewQ->pushProcessQ(&callbackFrame); |
| } |
| m_longExposurePreview = false; |
| } |
| } |
| } |
| newFrame->decRef(); |
| m_frameMgr->deleteFrame(newFrame); |
| //m_mainSetupQ[INDEX(entity->getPipeId())]->pushProcessQ(&newFrame); |
| CLOGV("DEBUG(%s[%d]):SCP done HAL-frameCount(%d)", __FUNCTION__, __LINE__, frame->getFrameCount()); |
| } else { |
| CLOGV("DEBUG(%s[%d]):SCP droped - SCP buffer is not ready HAL-frameCount(%d)", __FUNCTION__, __LINE__, frame->getFrameCount()); |
| |
| ret = frame->getDstBuffer(entity->getPipeId(), &buffer, m_previewFrameFactory->getNodeType(PIPE_SCP)); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| return ret; |
| } |
| |
| if (buffer.index >= 0) { |
| ret = m_scpBufferMgr->cancelBuffer(buffer.index, true); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):SCP buffer return fail", __FUNCTION__, __LINE__); |
| } |
| } |
| |
| /* For debug */ |
| /* m_previewFrameFactory->dump(); */ |
| |
| /* Comment out, because it included ISP */ |
| /* |
| newFrame = m_previewFrameFactory->createNewFrameOnlyOnePipe(PIPE_SCP, frame->getFrameCount()); |
| newFrame->setDstBuffer(PIPE_SCP, buffer); |
| newFrame->setFrameState(FRAME_STATE_SKIPPED); |
| |
| m_mainSetupQ[INDEX(entity->getPipeId())]->pushProcessQ(&newFrame); |
| */ |
| } |
| break; |
| default: |
| break; |
| } |
| |
| entity_state_complete: |
| |
| entity = curentity; |
| |
| ret = frame->setEntityState(entity->getPipeId(), ENTITY_STATE_COMPLETE); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setEntityState fail, pipeId(%d), state(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ENTITY_STATE_COMPLETE, ret); |
| return ret; |
| } |
| |
| if (frame->isComplete() == true) { |
| ret = m_removeFrameFromList(&m_processList, frame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):remove frame from processList fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| |
| frame->decRef(); |
| m_frameMgr->deleteFrame(frame); |
| } |
| |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_handlePreviewFrameFrontDual(ExynosCameraFrame *frame) |
| { |
| int ret = 0; |
| ExynosCameraFrameEntity *entity = NULL; |
| ExynosCameraFrameEntity *curentity = NULL; |
| ExynosCameraFrame *newFrame = NULL; |
| ExynosCameraFrame *fdFrame = NULL; |
| |
| ExynosCameraBuffer buffer; |
| ExynosCameraBuffer ispcBuffer; |
| int pipeID = 0; |
| int dummyPipeId = -1; |
| /* to handle the high speed frame rate */ |
| bool skipPreview = false; |
| int ratio = 1; |
| uint32_t minFps = 0, maxFps = 0; |
| uint32_t dispFps = EXYNOS_CAMERA_PREVIEW_FPS_REFERENCE; |
| uint32_t fvalid = 0; |
| uint32_t fcount = 0; |
| uint32_t skipCount = 0; |
| struct camera2_stream *shot_stream = NULL; |
| ExynosCameraBuffer resultBuffer; |
| camera2_node_group node_group_info_isp; |
| int32_t reprocessingBayerMode = m_exynosCameraParameters->getReprocessingBayerMode(); |
| int ispDstBufferIndex = -1; |
| |
| entity = frame->getFrameDoneFirstEntity(); |
| if (entity == NULL) { |
| CLOGE("ERR(%s[%d]):current entity is NULL frame(%d)", __FUNCTION__, __LINE__, frame->getFrameCount()); |
| /* TODO: doing exception handling */ |
| return true; |
| } |
| |
| curentity = entity; |
| |
| pipeID = entity->getPipeId(); |
| |
| |
| /* TODO: remove hard coding */ |
| switch(INDEX(entity->getPipeId())) { |
| case PIPE_3AA_ISP: |
| break; |
| case PIPE_3AC: |
| case PIPE_FLITE: |
| m_debugFpsCheck(entity->getPipeId()); |
| |
| ret = frame->getDstBuffer(entity->getPipeId(), &buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| return ret; |
| } |
| |
| m_setupEntity(PIPE_3AA, frame, &buffer, NULL); |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, PIPE_3AA); |
| m_previewFrameFactory->pushFrameToPipe(&frame, PIPE_3AA); |
| |
| break; |
| case PIPE_3AA: |
| m_debugFpsCheck(entity->getPipeId()); |
| |
| ret = frame->getSrcBuffer(entity->getPipeId(), &buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getSrcBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| return ret; |
| } |
| |
| if (buffer.index >= 0) { |
| ret = m_putBuffers(m_bayerBufferMgr, buffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):put Buffer fail", __FUNCTION__, __LINE__); |
| } |
| } |
| |
| newFrame = m_frameMgr->createFrame(m_exynosCameraParameters, 0); |
| m_mainSetupQ[INDEX(m_getBayerPipeId())]->pushProcessQ(&newFrame); |
| |
| CLOGV("DEBUG(%s[%d]):3AA_ISP frameCount(%d) frame.Count(%d)", |
| __FUNCTION__, __LINE__, |
| getMetaDmRequestFrameCount((struct camera2_shot_ext *)buffer.addr[1]), |
| frame->getFrameCount()); |
| |
| case PIPE_SCP: |
| if (m_exynosCameraParameters->getZoomPreviewWIthScaler()== true) { |
| CLOGV("INFO(%s[%d]): zoom preview with csc pipeId(%d) frame(%d)", __FUNCTION__, __LINE__, entity->getPipeId(), frame->getFrameCount()); |
| m_zoomPreviwWithCscQ->pushProcessQ(&frame); |
| break; |
| } else { |
| CLOGV("INFO(%s[%d]): zoom preview without csc pipeId(%d)", __FUNCTION__, __LINE__, entity->getPipeId()); |
| } |
| |
| case PIPE_GSC: |
| if (m_exynosCameraParameters->getZoomPreviewWIthScaler()== true) { |
| CLOGV("INFO(%s[%d]): zoom preview with csc pipeId(%d) frame(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), frame->getFrameCount()); |
| |
| dummyPipeId = (m_exynosCameraParameters->getTpuEnabledMode())? PIPE_DIS : PIPE_3AA; |
| ret = m_syncPrviewWithCSC(dummyPipeId, PIPE_GSC, frame); |
| if (ret < 0) { |
| CLOGW("WARN(%s[%d]):m_syncPrviewWithCSC failed frame(%d)", __FUNCTION__, __LINE__, frame->getFrameCount()); |
| } |
| |
| entity = frame->searchEntityByPipeId(dummyPipeId); |
| if (entity == NULL) { |
| CLOGE("ERR(%s[%d]):searchEntityByPipeId failed pipe(%d) frame(%d)", |
| __FUNCTION__, __LINE__, dummyPipeId, frame->getFrameCount()); |
| goto entity_state_complete; |
| } |
| } else { |
| CLOGV("INFO(%s[%d]): zoom preview with without csc pipeId(%d) frame(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), frame->getFrameCount()); |
| } |
| |
| buffer.index = -1; |
| |
| if (frame->getRequest(PIPE_ISPC) == true) { |
| ret = frame->getDstBuffer(entity->getPipeId(), &buffer, m_previewFrameFactory->getNodeType(PIPE_ISPC)); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):getSrcBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| } |
| } |
| |
| if (buffer.index >= 0) { |
| if (frame->getRequest(PIPE_ISPC) == true) { |
| entity_buffer_state_t bufferstate = ENTITY_BUFFER_STATE_NOREQ; |
| ret = frame->getDstBufferState(entity->getPipeId(), &bufferstate, m_previewFrameFactory->getNodeType(PIPE_ISPC)); |
| if (ret == NO_ERROR && bufferstate != ENTITY_BUFFER_STATE_ERROR) { |
| ret = m_sccCaptureSelector->manageFrameHoldList(frame, entity->getPipeId(), false, m_previewFrameFactory->getNodeType(PIPE_ISPC)); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):manageFrameHoldList fail", __FUNCTION__, __LINE__); |
| } |
| } else { |
| ret = m_putBuffers(m_sccBufferMgr, buffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_putBuffers(m_bayerBufferMgr, %d) fail", __FUNCTION__, __LINE__, buffer.index); |
| } |
| } |
| } |
| } |
| |
| frame->setMetaDataEnable(true); |
| |
| if (entity->getDstBufState() == ENTITY_BUFFER_STATE_ERROR) { |
| if (frame->getFrameState() != FRAME_STATE_SKIPPED) { |
| ret = frame->getDstBuffer(entity->getPipeId(), &buffer, m_previewFrameFactory->getNodeType(PIPE_SCP)); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| return ret; |
| } |
| |
| if (buffer.index >= 0) { |
| ret = m_scpBufferMgr->cancelBuffer(buffer.index); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):SCP buffer return fail", __FUNCTION__, __LINE__); |
| } |
| /* For debug */ |
| /* m_previewFrameFactory->dump(); */ |
| |
| /* Comment out, because it included ISP */ |
| /* |
| newFrame = m_previewFrameFactory->createNewFrameOnlyOnePipe(PIPE_SCP, frame->getFrameCount()); |
| newFrame->setDstBuffer(PIPE_SCP, buffer); |
| newFrame->setFrameState(FRAME_STATE_SKIPPED); |
| |
| m_mainSetupQ[INDEX(entity->getPipeId())]->pushProcessQ(&newFrame); |
| */ |
| } |
| CLOGV("DEBUG(%s[%d]):SCP done HAL-frameCount(%d)", __FUNCTION__, __LINE__, frame->getFrameCount()); |
| } else if (entity->getDstBufState() == ENTITY_BUFFER_STATE_COMPLETE) { |
| m_debugFpsCheck(entity->getPipeId()); |
| |
| ret = frame->getDstBuffer(entity->getPipeId(), &buffer, m_previewFrameFactory->getNodeType(PIPE_SCP)); |
| |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| return ret; |
| } |
| |
| /* TO DO : skip frame for HDR */ |
| shot_stream = (struct camera2_stream *)buffer.addr[2]; |
| |
| if (shot_stream != NULL) { |
| getStreamFrameValid(shot_stream, &fvalid); |
| getStreamFrameCount(shot_stream, &fcount); |
| } else { |
| CLOGE("ERR(%s[%d]):shot_stream is NULL", __FUNCTION__, __LINE__); |
| fvalid = false; |
| fcount = 0; |
| } |
| |
| /* drop preview frame if lcd supported frame rate < scp frame rate */ |
| frame->getFpsRange(&minFps, &maxFps); |
| if (dispFps < maxFps) { |
| ratio = (int)((maxFps * 10 / dispFps) / 10); |
| m_displayPreviewToggle = (m_displayPreviewToggle + 1) % ratio; |
| skipPreview = (m_displayPreviewToggle == 0) ? true : false; |
| #ifdef DEBUG |
| CLOGE("DEBUG(%s[%d]):preview frame skip! frameCount(%d) (m_displayPreviewToggle=%d, maxFps=%d, dispFps=%d, ratio=%d, skipPreview=%d)", |
| __FUNCTION__, __LINE__, frame->getFrameCount(), m_displayPreviewToggle, maxFps, dispFps, ratio, (int)skipPreview); |
| #endif |
| } |
| |
| newFrame = m_previewFrameFactory->createNewFrameOnlyOnePipe(PIPE_SCP, frame->getFrameCount()); |
| |
| newFrame->setDstBuffer(PIPE_SCP, buffer); |
| |
| m_exynosCameraParameters->getFrameSkipCount(&m_frameSkipCount); |
| if (m_frameSkipCount > 0) { |
| CLOGD("INFO(%s[%d]):Skip frame for frameSkipCount(%d) buffer.index(%d)", |
| __FUNCTION__, __LINE__, m_frameSkipCount, buffer.index); |
| |
| newFrame->setFrameState(FRAME_STATE_SKIPPED); |
| if (buffer.index >= 0) { |
| ret = m_scpBufferMgr->cancelBuffer(buffer.index); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):SCP buffer return fail", __FUNCTION__, __LINE__); |
| } |
| } else { |
| if (m_skipReprocessing == true) |
| m_skipReprocessing = false; |
| nsecs_t timeStamp = (nsecs_t)frame->getTimeStamp(); |
| if (m_getRecordingEnabled() == true |
| && m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_VIDEO_FRAME)) { |
| if (timeStamp <= 0L) { |
| CLOGE("WARN(%s[%d]):timeStamp(%lld) Skip", __FUNCTION__, __LINE__, (long long)timeStamp); |
| } else { |
| if (m_exynosCameraParameters->doCscRecording() == true) { |
| /* get Recording Image buffer */ |
| int bufIndex = -2; |
| ExynosCameraBuffer recordingBuffer; |
| ret = m_recordingBufferMgr->getBuffer(&bufIndex, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL, &recordingBuffer); |
| if (ret < 0 || bufIndex < 0) { |
| if ((++m_recordingFrameSkipCount % 100) == 0) { |
| CLOGE("ERR(%s[%d]): Recording buffer is not available!! Recording Frames are Skipping(%d frames) (bufIndex=%d)", |
| __FUNCTION__, __LINE__, m_recordingFrameSkipCount, bufIndex); |
| m_recordingBufferMgr->printBufferQState(); |
| } |
| } else { |
| if (m_recordingFrameSkipCount != 0) { |
| CLOGE("ERR(%s[%d]): Recording buffer is not available!! Recording Frames are Skipped(%d frames) (bufIndex=%d) (recordingQ=%d)", |
| __FUNCTION__, __LINE__, m_recordingFrameSkipCount, bufIndex, m_recordingQ->getSizeOfProcessQ()); |
| m_recordingFrameSkipCount = 0; |
| m_recordingBufferMgr->printBufferQState(); |
| } |
| |
| ret = m_doPrviewToRecordingFunc(PIPE_GSC_VIDEO, buffer, recordingBuffer, timeStamp); |
| if (ret < 0) { |
| CLOGW("WARN(%s[%d]):recordingCallback Skip", __FUNCTION__, __LINE__); |
| } |
| } |
| } else { |
| m_recordingTimeStamp[buffer.index] = timeStamp; |
| |
| if (m_recordingStartTimeStamp == 0) { |
| m_recordingStartTimeStamp = timeStamp; |
| CLOGI("INFO(%s[%d]):m_recordingStartTimeStamp=%lld", |
| __FUNCTION__, __LINE__, (long long)m_recordingStartTimeStamp); |
| } |
| |
| if ((0L < timeStamp) |
| && (m_lastRecordingTimeStamp < timeStamp) |
| && (m_recordingStartTimeStamp <= timeStamp)) { |
| if (m_getRecordingEnabled() == true |
| && m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_VIDEO_FRAME)) { |
| #ifdef CHECK_MONOTONIC_TIMESTAMP |
| CLOGD("DEBUG(%s[%d]):m_dataCbTimestamp::recordingFrameIndex=%d, recordingTimeStamp=%lld, fd[0]=%d", |
| __FUNCTION__, __LINE__, buffer.index, (long long)timeStamp, buffer.fd[0]); |
| #endif |
| #ifdef DEBUG |
| CLOGD("DEBUG(%s[%d]): - lastTimeStamp(%lld), systemTime(%lld), recordingStart(%lld)", |
| __FUNCTION__, __LINE__, |
| (long long)m_lastRecordingTimeStamp, |
| (long long)systemTime(SYSTEM_TIME_MONOTONIC), |
| (long long)m_recordingStartTimeStamp); |
| #endif |
| |
| if (m_recordingBufAvailable[buffer.index] == false) { |
| CLOGW("WARN(%s[%d]):recordingFrameIndex(%d) didn't release yet !!! drop the frame !!! " |
| " timeStamp(%lld) m_recordingBufAvailable(%d)", |
| __FUNCTION__, __LINE__, buffer.index, (long long)timeStamp, (int)m_recordingBufAvailable[buffer.index]); |
| } else { |
| struct VideoNativeHandleMetadata *recordAddrs = NULL; |
| |
| recordAddrs = (struct VideoNativeHandleMetadata *)m_recordingCallbackHeap->data; |
| recordAddrs[buffer.index].eType = kMetadataBufferTypeNativeHandleSource; |
| |
| native_handle* handle = native_handle_create(2, 1); |
| handle->data[0] = (int32_t) buffer.fd[0]; |
| handle->data[1] = (int32_t) buffer.fd[1]; |
| handle->data[2] = (int32_t) buffer.index; |
| |
| recordAddrs[buffer.index].pHandle = handle; |
| |
| m_recordingBufAvailable[buffer.index] = false; |
| m_lastRecordingTimeStamp = timeStamp; |
| |
| m_dataCbTimestamp( |
| timeStamp, |
| CAMERA_MSG_VIDEO_FRAME, |
| m_recordingCallbackHeap, |
| buffer.index, |
| m_callbackCookie); |
| } |
| } |
| } else { |
| CLOGW("WARN(%s[%d]):recordingFrameIndex=%d, timeStamp(%lld) invalid -" |
| " lastTimeStamp(%lld), systemTime(%lld), recordingStart(%lld), m_recordingBufAvailable(%d)", |
| __FUNCTION__, __LINE__, buffer.index, (long long)timeStamp, |
| (long long)m_lastRecordingTimeStamp, |
| (long long)systemTime(SYSTEM_TIME_MONOTONIC), |
| (long long)m_recordingStartTimeStamp, |
| (int)m_recordingBufAvailable[buffer.index]); |
| m_recordingTimeStamp[buffer.index] = 0L; |
| } |
| } |
| } |
| } |
| ExynosCameraBuffer callbackBuffer; |
| ExynosCameraFrame *callbackFrame = NULL; |
| callbackFrame = m_previewFrameFactory->createNewFrameOnlyOnePipe(PIPE_SCP, frame->getFrameCount()); |
| frame->getDstBuffer(entity->getPipeId(), &callbackBuffer, m_previewFrameFactory->getNodeType(PIPE_SCP)); |
| m_copyMetaFrameToFrame(frame, callbackFrame, true, true); |
| |
| callbackFrame->setDstBuffer(PIPE_SCP, callbackBuffer); |
| |
| if (((m_exynosCameraParameters->getPreviewBufferCount() == NUM_PREVIEW_BUFFERS + NUM_PREVIEW_SPARE_BUFFERS && |
| m_previewQ->getSizeOfProcessQ() >= 2) || |
| (m_exynosCameraParameters->getPreviewBufferCount() == NUM_PREVIEW_BUFFERS && |
| m_previewQ->getSizeOfProcessQ() >= 1)) && |
| (m_previewThread->isRunning() == true)) { |
| CLOGW("WARN(%s[%d]):Frames are stacked in previewQ. Skip frame. PreviewQ(%d), PreviewBufferCount(%d)", |
| __FUNCTION__, __LINE__, |
| m_previewQ->getSizeOfProcessQ(), |
| m_exynosCameraParameters->getPreviewBufferCount()); |
| |
| newFrame->setFrameState(FRAME_STATE_SKIPPED); |
| if (buffer.index >= 0) { |
| ret = m_scpBufferMgr->cancelBuffer(buffer.index); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):SCP buffer return fail", __FUNCTION__, __LINE__); |
| } |
| |
| callbackFrame->decRef(); |
| m_frameMgr->deleteFrame(callbackFrame); |
| callbackFrame = NULL; |
| } else if((m_exynosCameraParameters->getFastFpsMode() == 2) && (m_exynosCameraParameters->getRecordingHint() == 1)) { |
| m_skipCount++; |
| #ifdef SAMSUNG_DOF |
| if((m_exynosCameraParameters->getShotMode() == SHOT_MODE_SEQUENCE && m_skipCount%4 != 0) |
| || (m_exynosCameraParameters->getShotMode() != SHOT_MODE_SEQUENCE && m_skipCount%2 == 1)) { |
| CLOGV("INFO(%s[%d]):fast fps mode skip frame(%d) ", __FUNCTION__, __LINE__,m_skipCount); |
| newFrame->setFrameState(FRAME_STATE_SKIPPED); |
| if (buffer.index >= 0) { |
| ret = m_scpBufferMgr->cancelBuffer(buffer.index); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):SCP buffer return fail", __FUNCTION__, __LINE__); |
| } |
| callbackFrame->decRef(); |
| m_frameMgr->deleteFrame(callbackFrame); |
| callbackFrame = NULL; |
| } else |
| #endif |
| { |
| CLOGV("INFO(%s[%d]):push frame to previewQ", __FUNCTION__, __LINE__); |
| m_previewQ->pushProcessQ(&callbackFrame); |
| } |
| } else { |
| CLOGV("INFO(%s[%d]):push frame to previewQ", __FUNCTION__, __LINE__); |
| m_previewQ->pushProcessQ(&callbackFrame); |
| } |
| } |
| newFrame->decRef(); |
| m_frameMgr->deleteFrame(newFrame); |
| //m_mainSetupQ[INDEX(entity->getPipeId())]->pushProcessQ(&newFrame); |
| CLOGV("DEBUG(%s[%d]):SCP done HAL-frameCount(%d)", __FUNCTION__, __LINE__, frame->getFrameCount()); |
| } else { |
| CLOGV("DEBUG(%s[%d]):SCP droped - SCP buffer is not ready HAL-frameCount(%d)", __FUNCTION__, __LINE__, frame->getFrameCount()); |
| |
| ret = frame->getDstBuffer(entity->getPipeId(), &buffer, m_previewFrameFactory->getNodeType(PIPE_SCP)); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| return ret; |
| } |
| |
| if (buffer.index >= 0) { |
| ret = m_scpBufferMgr->cancelBuffer(buffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):SCP buffer return fail", __FUNCTION__, __LINE__); |
| } |
| } |
| } |
| break; |
| default: |
| break; |
| } |
| |
| entity_state_complete: |
| |
| entity = curentity; |
| |
| ret = frame->setEntityState(entity->getPipeId(), ENTITY_STATE_COMPLETE); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setEntityState fail, pipeId(%d), state(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ENTITY_STATE_COMPLETE, ret); |
| return ret; |
| } |
| |
| if (frame->isComplete() == true) { |
| ret = m_removeFrameFromList(&m_processList, frame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):remove frame from processList fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| |
| frame->decRef(); |
| m_frameMgr->deleteFrame(frame); |
| } |
| |
| return NO_ERROR; |
| } |
| |
| bool ExynosCamera::m_frameFactoryInitThreadFunc(void) |
| { |
| CLOGI("INFO(%s[%d]): -IN-", __FUNCTION__, __LINE__); |
| |
| #ifdef DEBUG |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| #endif |
| bool loop = false; |
| status_t ret = NO_ERROR; |
| |
| ExynosCameraFrameFactory *framefactory = NULL; |
| |
| ret = m_frameFactoryQ->waitAndPopProcessQ(&framefactory); |
| if (m_flagThreadStop == true) { |
| CLOGI("INFO(%s[%d]):m_flagThreadStop(%d)", __FUNCTION__, __LINE__, m_flagThreadStop); |
| return false; |
| } |
| |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto func_exit; |
| } |
| |
| if (framefactory == NULL) { |
| CLOGE("ERR(%s[%d]):framefactory is NULL", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| if (framefactory->isCreated() == false) { |
| CLOGD("DEBUG(%s[%d]):framefactory create", __FUNCTION__, __LINE__); |
| framefactory->create(false); |
| } else { |
| CLOGD("DEBUG(%s[%d]):framefactory already create", __FUNCTION__, __LINE__); |
| } |
| |
| func_exit: |
| if (0 < m_frameFactoryQ->getSizeOfProcessQ()) { |
| if (m_previewEnabled == true) { |
| loop = true; |
| } else { |
| CLOGW("WARN(%s[%d]):Sudden stopPreview. so, stop making frameFactory (m_frameFactoryQ->getSizeOfProcessQ() : %d)", |
| __FUNCTION__, __LINE__, m_frameFactoryQ->getSizeOfProcessQ()); |
| loop = false; |
| } |
| } |
| |
| CLOGI("INFO(%s[%d]):m_framefactoryThread end loop(%d) m_frameFactoryQ(%d), m_previewEnabled(%d)", |
| __FUNCTION__, __LINE__, loop, m_frameFactoryQ->getSizeOfProcessQ(), m_previewEnabled); |
| |
| CLOGI("INFO(%s[%d]): -OUT-", __FUNCTION__, __LINE__); |
| |
| return loop; |
| } |
| |
| bool ExynosCamera::m_previewThreadFunc(void) |
| { |
| #ifdef DEBUG |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| #endif |
| |
| int ret = 0; |
| bool loop = true; |
| int pipeId = 0; |
| int pipeIdCsc = 0; |
| int maxbuffers = 0; |
| #ifdef USE_CAMERA_PREVIEW_FRAME_SCHEDULER |
| uint32_t curMinFps = 0; |
| uint32_t curMaxFps = 0; |
| #endif |
| ExynosCameraBuffer buffer; |
| ExynosCameraFrame *frame = NULL; |
| nsecs_t timeStamp = 0; |
| int frameCount = -1; |
| frame_queue_t *previewQ; |
| |
| #ifdef USE_CAMERA_PREVIEW_FRAME_SCHEDULER |
| m_exynosCameraParameters->getPreviewFpsRange(&curMinFps, &curMaxFps); |
| |
| /* Check the Slow/Fast Motion Scenario - sensor : 120fps, preview : 60fps */ |
| if(((curMinFps == 120) && (curMaxFps == 120)) |
| || ((curMinFps == 240) && (curMaxFps == 240))) { |
| CLOGV("(%s[%d]) : Change PreviewDuration from (%d,%d) to (60000, 60000)", __FUNCTION__, __LINE__, curMinFps, curMaxFps); |
| curMinFps = 60; |
| curMaxFps = 60; |
| } |
| #endif |
| |
| pipeId = PIPE_SCP; |
| pipeIdCsc = PIPE_GSC; |
| |
| previewQ = m_previewQ; |
| |
| CLOGV("INFO(%s[%d]):wait previewQ", __FUNCTION__, __LINE__); |
| ret = previewQ->waitAndPopProcessQ(&frame); |
| if (m_flagThreadStop == true) { |
| CLOGI("INFO(%s[%d]):m_flagThreadStop(%d)", __FUNCTION__, __LINE__, m_flagThreadStop); |
| |
| if (frame != NULL) { |
| frame->decRef(); |
| m_frameMgr->deleteFrame(frame); |
| frame = NULL; |
| } |
| |
| return false; |
| } |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| ret = INVALID_OPERATION; |
| goto func_exit; |
| } |
| |
| if (frame == NULL) { |
| CLOGE("ERR(%s[%d]):frame is NULL", __FUNCTION__, __LINE__); |
| ret = INVALID_OPERATION; |
| goto func_exit; |
| } |
| |
| CLOGV("INFO(%s[%d]):get frame from previewQ", __FUNCTION__, __LINE__); |
| timeStamp = (nsecs_t)frame->getTimeStamp(); |
| frameCount = frame->getFrameCount(); |
| ret = frame->getDstBuffer(pipeId, &buffer); |
| |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| /* TODO: doing exception handling */ |
| goto func_exit; |
| } |
| |
| /* ------------- frome here "frame" cannot use ------------- */ |
| CLOGV("INFO(%s[%d]):push frame to previewReturnQ", __FUNCTION__, __LINE__); |
| if(m_exynosCameraParameters->increaseMaxBufferOfPreview()) { |
| maxbuffers = m_exynosCameraParameters->getPreviewBufferCount(); |
| } else { |
| maxbuffers = (int)m_exynosconfig->current->bufInfo.num_preview_buffers; |
| } |
| |
| if (buffer.index < 0 || buffer.index >= maxbuffers ) { |
| CLOGE("ERR(%s[%d]):Out of Index! (Max: %d, Index: %d)", __FUNCTION__, __LINE__, maxbuffers, buffer.index); |
| goto func_exit; |
| } |
| |
| CLOGV("INFO(%s[%d]):m_previewQ->getSizeOfProcessQ(%d) m_scpBufferMgr->getNumOfAvailableBuffer(%d)", __FUNCTION__, __LINE__, |
| previewQ->getSizeOfProcessQ(), m_scpBufferMgr->getNumOfAvailableBuffer()); |
| |
| /* Prevent displaying unprocessed beauty images in beauty shot. */ |
| if ((m_exynosCameraParameters->getShotMode() == SHOT_MODE_BEAUTY_FACE) |
| #ifdef LLS_CAPTURE |
| || (m_exynosCameraParameters->getLLSOn() == true && getCameraId() == CAMERA_ID_FRONT) |
| #endif |
| ) { |
| if (m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME) && |
| checkBit(&m_callbackState, CALLBACK_STATE_COMPRESSED_IMAGE)) { |
| CLOGV("INFO(%s[%d]):skip the preview callback and the preview display while compressed callback.", |
| __FUNCTION__, __LINE__); |
| ret = m_scpBufferMgr->cancelBuffer(buffer.index); |
| goto func_exit; |
| } |
| } |
| |
| if ((m_previewWindow == NULL) || |
| (m_getRecordingEnabled() == true) || |
| (m_exynosCameraParameters->getPreviewBufferCount() == NUM_PREVIEW_BUFFERS + NUM_PREVIEW_SPARE_BUFFERS && |
| m_scpBufferMgr->getNumOfAvailableAndNoneBuffer() > 4 && |
| previewQ->getSizeOfProcessQ() < 2) || |
| #ifdef SUPPORT_SW_VDIS |
| (m_exynosCameraParameters->getPreviewBufferCount() == NUM_VDIS_BUFFERS && |
| m_scpBufferMgr->getNumOfAvailableAndNoneBuffer() > 2 && |
| previewQ->getSizeOfProcessQ() < 1) || |
| #endif /*SUPPORT_SW_VDIS*/ |
| (m_exynosCameraParameters->getPreviewBufferCount() == NUM_PREVIEW_BUFFERS && |
| m_scpBufferMgr->getNumOfAvailableAndNoneBuffer() > 2 && |
| previewQ->getSizeOfProcessQ() < 1)) { |
| if (m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME) && |
| m_highResolutionCallbackRunning == false) { |
| ExynosCameraBuffer previewCbBuffer; |
| |
| ret = m_setPreviewCallbackBuffer(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_setPreviewCallback Buffer fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| int bufIndex = -2; |
| m_previewCallbackBufferMgr->getBuffer(&bufIndex, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL, &previewCbBuffer); |
| |
| ExynosCameraFrame *newFrame = NULL; |
| |
| newFrame = m_previewFrameFactory->createNewFrameOnlyOnePipe(pipeIdCsc); |
| if (newFrame == NULL) { |
| CLOGE("ERR(%s):newFrame is NULL", __FUNCTION__); |
| return UNKNOWN_ERROR; |
| } |
| |
| m_copyMetaFrameToFrame(frame, newFrame, true, true); |
| |
| ret = m_doPreviewToCallbackFunc(pipeIdCsc, newFrame, buffer, previewCbBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_doPreviewToCallbackFunc fail", __FUNCTION__, __LINE__); |
| m_previewCallbackBufferMgr->putBuffer(bufIndex, EXYNOS_CAMERA_BUFFER_POSITION_NONE); |
| m_scpBufferMgr->cancelBuffer(buffer.index); |
| goto func_exit; |
| } else { |
| if (m_exynosCameraParameters->getCallbackNeedCopy2Rendering() == true) { |
| ret = m_doCallbackToPreviewFunc(pipeIdCsc, frame, previewCbBuffer, buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_doCallbackToPreviewFunc fail", __FUNCTION__, __LINE__); |
| m_previewCallbackBufferMgr->putBuffer(bufIndex, EXYNOS_CAMERA_BUFFER_POSITION_NONE); |
| m_scpBufferMgr->cancelBuffer(buffer.index); |
| goto func_exit; |
| } |
| } |
| } |
| |
| if (newFrame != NULL) { |
| newFrame->decRef(); |
| m_frameMgr->deleteFrame(newFrame); |
| newFrame = NULL; |
| } |
| |
| m_previewCallbackBufferMgr->putBuffer(bufIndex, EXYNOS_CAMERA_BUFFER_POSITION_NONE); |
| } |
| |
| if (m_previewWindow != NULL) { |
| if (timeStamp > 0L) { |
| m_previewWindow->set_timestamp(m_previewWindow, (int64_t)timeStamp); |
| } else { |
| uint32_t fcount = 0; |
| getStreamFrameCount((struct camera2_stream *)buffer.addr[2], &fcount); |
| CLOGW("WRN(%s[%d]): frameCount(%d)(%d), Invalid timeStamp(%lld)", |
| __FUNCTION__, __LINE__, |
| frameCount, |
| fcount, |
| (long long)timeStamp); |
| } |
| } |
| |
| #ifdef FIRST_PREVIEW_TIME_CHECK |
| if (m_flagFirstPreviewTimerOn == true) { |
| ExynosCameraActivityAutofocus *autoFocusMgr = m_exynosCameraActivityControl->getAutoFocusMgr(); |
| m_firstPreviewTimer.stop(); |
| m_flagFirstPreviewTimerOn = false; |
| |
| CLOGD("DEBUG(%s[%d]):m_firstPreviewTimer stop", __FUNCTION__, __LINE__); |
| |
| CLOGD("DEBUG(%s[%d]):============= First Preview time ==================", "m_printExynosCameraInfo", __LINE__); |
| CLOGD("DEBUG(%s[%d]):= startPreview ~ first frame : %d msec", "m_printExynosCameraInfo", __LINE__, (int)m_firstPreviewTimer.durationMsecs()); |
| CLOGD("DEBUG(%s[%d]):===================================================", "m_printExynosCameraInfo", __LINE__); |
| autoFocusMgr->displayAFInfo(); |
| } |
| #endif |
| |
| #ifdef SAMSUNG_SENSOR_LISTENER |
| #ifdef SAMSUNG_HRM |
| if(m_uv_rayHandle != NULL) { |
| ret = sensor_listener_get_data(m_uv_rayHandle, ST_UV_RAY, &m_uv_rayListenerData, false); |
| if(ret < 0) { |
| CLOGW("WRN(%s[%d]:%d):skip the HRM data", __FUNCTION__, __LINE__, ret); |
| } else { |
| m_exynosCameraParameters->m_setHRM(m_uv_rayListenerData.uv_ray.ir_data, m_uv_rayListenerData.uv_ray.status); |
| } |
| } |
| #endif |
| |
| #ifdef SAMSUNG_LIGHT_IR |
| if(m_light_irHandle != NULL) { |
| ret = sensor_listener_get_data(m_light_irHandle, ST_LIGHT_IR, &m_light_irListenerData, false); |
| if(ret < 0) { |
| CLOGW("WRN(%s[%d]:%d):skip the Light IR data", __FUNCTION__, __LINE__, ret); |
| } else { |
| m_exynosCameraParameters->m_setLight_IR(m_light_irListenerData); |
| } |
| } |
| #endif |
| |
| #ifdef SAMSUNG_GYRO |
| if(m_gyroHandle != NULL) { |
| ret = sensor_listener_get_data(m_gyroHandle, ST_GYROSCOPE, &m_gyroListenerData, false); |
| if(ret < 0) { |
| CLOGW("WRN(%s[%d]:%d):skip the Gyro data", __FUNCTION__, __LINE__, ret); |
| } else { |
| m_exynosCameraParameters->m_setGyro(m_gyroListenerData); |
| } |
| } |
| #endif |
| #endif /* SAMSUNG_SENSOR_LISTENER */ |
| |
| #ifdef SUPPORT_SW_VDIS |
| if(m_swVDIS_Mode) { |
| int swVDIS_InW, swVDIS_InH, swVDIS_OutW, swVDIS_OutH; |
| int swVDIS_StartX, swVDIS_StartY; |
| |
| m_exynosCameraParameters->getHwPreviewSize(&swVDIS_OutW, &swVDIS_OutH); |
| swVDIS_InW = swVDIS_OutW; |
| swVDIS_InH = swVDIS_OutH; |
| m_swVDIS_AdjustPreviewSize(&swVDIS_OutW, &swVDIS_OutH); |
| |
| swVDIS_StartX = (swVDIS_InW-swVDIS_OutW)/2; |
| swVDIS_StartY = (swVDIS_InH-swVDIS_OutH)/2; |
| |
| if (m_previewWindow != NULL) { |
| m_previewWindow->set_crop(m_previewWindow, swVDIS_StartX, swVDIS_StartY, |
| swVDIS_OutW + swVDIS_StartX, swVDIS_OutH + swVDIS_StartY); |
| } |
| } |
| #endif /*SUPPORT_SW_VDIS*/ |
| #ifdef USE_FASTMOTION_CROP |
| if(m_exynosCameraParameters->getShotMode() == SHOT_MODE_FASTMOTION) { |
| int inW, inH, outW, outH, startX, startY; |
| |
| m_exynosCameraParameters->getPreviewSize(&inW, &inH); |
| outW = ALIGN_DOWN((int)(inW * FASTMOTION_CROP_RATIO), PREVIEW_OPS_CROP_ALIGN); |
| outH = ALIGN_DOWN((int)(inH * FASTMOTION_CROP_RATIO), PREVIEW_OPS_CROP_ALIGN); |
| startX = ALIGN_DOWN((inW - outW) / 2, PREVIEW_OPS_CROP_ALIGN); |
| startY = ALIGN_DOWN((inH - outH) / 2, PREVIEW_OPS_CROP_ALIGN); |
| |
| if (m_previewWindow != NULL) { |
| m_previewWindow->set_crop(m_previewWindow, startX, startY, startX + outW, startY + outH); |
| } |
| } |
| #endif /* USE_FASTMOTION_CROP */ |
| |
| /* Prevent displaying unprocessed beauty images in beauty shot. */ |
| if ((m_exynosCameraParameters->getShotMode() == SHOT_MODE_BEAUTY_FACE) |
| #ifdef LLS_CAPTURE |
| || (m_exynosCameraParameters->getLLSOn() == true && getCameraId() == CAMERA_ID_FRONT) |
| #endif |
| ) { |
| if (m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME) && |
| checkBit(&m_callbackState, CALLBACK_STATE_COMPRESSED_IMAGE)) { |
| CLOGV("INFO(%s[%d]):skip the preview callback and the preview display while compressed callback.", |
| __FUNCTION__, __LINE__); |
| ret = m_scpBufferMgr->cancelBuffer(buffer.index); |
| goto func_exit; |
| } |
| } |
| |
| #ifdef USE_CAMERA_PREVIEW_FRAME_SCHEDULER |
| if (((m_getRecordingEnabled() == true) && (curMinFps == curMaxFps) |
| && (m_exynosCameraParameters->getShotMode() != SHOT_MODE_SEQUENCE)) |
| || (m_exynosCameraParameters->getVRMode() == 1)) { |
| if(previewQ->getSizeOfProcessQ() < 1) { |
| m_previewFrameScheduler->m_schedulePreviewFrame(curMaxFps); |
| } |
| } |
| #endif |
| |
| /* display the frame */ |
| { |
| ret = m_putBuffers(m_scpBufferMgr, buffer.index); |
| } |
| |
| if (ret < 0) { |
| /* TODO: error handling */ |
| CLOGE("ERR(%s[%d]):put Buffer fail", __FUNCTION__, __LINE__); |
| } |
| } else { |
| ALOGW("WARN(%s[%d]):Preview frame buffer is canceled." |
| "PreviewThread is blocked or too many buffers are in Service." |
| "PreviewBufferCount(%d), ScpBufferMgr(%d), PreviewQ(%d)", |
| __FUNCTION__, __LINE__, |
| m_exynosCameraParameters->getPreviewBufferCount(), |
| m_scpBufferMgr->getNumOfAvailableAndNoneBuffer(), |
| previewQ->getSizeOfProcessQ()); |
| ret = m_scpBufferMgr->cancelBuffer(buffer.index); |
| } |
| |
| func_exit: |
| |
| if (frame != NULL) { |
| frame->decRef(); |
| m_frameMgr->deleteFrame(frame); |
| frame = NULL; |
| } |
| |
| return loop; |
| } |
| |
| status_t ExynosCamera::m_setCallbackBufferInfo(ExynosCameraBuffer *callbackBuf, char *baseAddr) |
| { |
| /* |
| * If it is not 16-aligend, shrink down it as 16 align. ex) 1080 -> 1072 |
| * But, memory is set on Android format. so, not aligned area will be black. |
| */ |
| int dst_width = 0, dst_height = 0, dst_crop_width = 0, dst_crop_height = 0; |
| int dst_format = m_exynosCameraParameters->getPreviewFormat(); |
| |
| m_exynosCameraParameters->getPreviewSize(&dst_width, &dst_height); |
| dst_crop_width = dst_width; |
| dst_crop_height = dst_height; |
| |
| if (dst_format == V4L2_PIX_FMT_NV21 || |
| dst_format == V4L2_PIX_FMT_NV21M) { |
| |
| callbackBuf->size[0] = (dst_width * dst_height); |
| callbackBuf->size[1] = (dst_width * dst_height) / 2; |
| |
| callbackBuf->addr[0] = baseAddr; |
| callbackBuf->addr[1] = callbackBuf->addr[0] + callbackBuf->size[0]; |
| } else if (dst_format == V4L2_PIX_FMT_YVU420 || |
| dst_format == V4L2_PIX_FMT_YVU420M) { |
| callbackBuf->size[0] = dst_width * dst_height; |
| callbackBuf->size[1] = dst_width / 2 * dst_height / 2; |
| callbackBuf->size[2] = callbackBuf->size[1]; |
| |
| callbackBuf->addr[0] = baseAddr; |
| callbackBuf->addr[1] = callbackBuf->addr[0] + callbackBuf->size[0]; |
| callbackBuf->addr[2] = callbackBuf->addr[1] + callbackBuf->size[1]; |
| } |
| |
| CLOGV("DEBUG(%s): dst_size(%dx%d), dst_crop_size(%dx%d)", __FUNCTION__, dst_width, dst_height, dst_crop_width, dst_crop_height); |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_doPreviewToCallbackFunc( |
| int32_t pipeId, |
| ExynosCameraFrame *newFrame, |
| ExynosCameraBuffer previewBuf, |
| ExynosCameraBuffer callbackBuf) |
| { |
| CLOGV("DEBUG(%s): converting preview to callback buffer", __FUNCTION__); |
| |
| int ret = 0; |
| status_t statusRet = NO_ERROR; |
| |
| int hwPreviewW = 0, hwPreviewH = 0; |
| int hwPreviewFormat = m_exynosCameraParameters->getHwPreviewFormat(); |
| bool useCSC = m_exynosCameraParameters->getCallbackNeedCSC(); |
| |
| ExynosCameraDurationTimer probeTimer; |
| int probeTimeMSEC; |
| uint32_t fcount = 0; |
| camera_frame_metadata_t m_Metadata; |
| |
| m_exynosCameraParameters->getHwPreviewSize(&hwPreviewW, &hwPreviewH); |
| #ifdef SUPPORT_SW_VDIS |
| if(m_swVDIS_Mode) |
| m_swVDIS_AdjustPreviewSize(&hwPreviewW, &hwPreviewH); |
| #endif /*SUPPORT_SW_VDIS*/ |
| |
| ExynosRect srcRect, dstRect; |
| |
| camera_memory_t *previewCallbackHeap = NULL; |
| previewCallbackHeap = m_getMemoryCb(callbackBuf.fd[0], callbackBuf.size[0], 1, m_callbackCookie); |
| if (!previewCallbackHeap || previewCallbackHeap->data == MAP_FAILED) { |
| CLOGE("ERR(%s[%d]):m_getMemoryCb(%d) fail", __FUNCTION__, __LINE__, callbackBuf.size[0]); |
| statusRet = INVALID_OPERATION; |
| goto done; |
| } |
| |
| ret = m_setCallbackBufferInfo(&callbackBuf, (char *)previewCallbackHeap->data); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): setCallbackBufferInfo fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| statusRet = INVALID_OPERATION; |
| goto done; |
| } |
| |
| if (m_flagThreadStop == true || m_previewEnabled == false) { |
| CLOGE("ERR(%s[%d]): preview was stopped!", __FUNCTION__, __LINE__); |
| statusRet = INVALID_OPERATION; |
| goto done; |
| } |
| |
| memset(&m_Metadata, 0, sizeof(camera_frame_metadata_t)); |
| #ifdef SAMSUNG_TIMESTAMP_BOOT |
| m_Metadata.timestamp = newFrame->getTimeStampBoot(); |
| CLOGV("INFO(%s[%d]): timestamp:%lldms!", __FUNCTION__, __LINE__, newFrame->getTimeStampBoot()); |
| #endif |
| ret = m_calcPreviewGSCRect(&srcRect, &dstRect); |
| |
| if (useCSC) { |
| ret = newFrame->setSrcRect(pipeId, &srcRect); |
| ret = newFrame->setDstRect(pipeId, &dstRect); |
| |
| ret = m_setupEntity(pipeId, newFrame, &previewBuf, &callbackBuf); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId, ret); |
| statusRet = INVALID_OPERATION; |
| goto done; |
| } |
| m_previewFrameFactory->setOutputFrameQToPipe(m_previewCallbackGscFrameDoneQ, pipeId); |
| m_previewFrameFactory->pushFrameToPipe(&newFrame, pipeId); |
| |
| CLOGV("INFO(%s[%d]):wait preview callback output", __FUNCTION__, __LINE__); |
| ret = m_previewCallbackGscFrameDoneQ->waitAndPopProcessQ(&newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| /* TODO: doing exception handling */ |
| statusRet = INVALID_OPERATION; |
| goto done; |
| } |
| if (newFrame == NULL) { |
| CLOGE("ERR(%s[%d]):newFrame is NULL", __FUNCTION__, __LINE__); |
| statusRet = INVALID_OPERATION; |
| goto done; |
| } |
| CLOGV("INFO(%s[%d]):preview callback done", __FUNCTION__, __LINE__); |
| |
| #if 0 |
| int remainedH = m_orgPreviewRect.h - dst_height; |
| |
| if (remainedH != 0) { |
| char *srcAddr = NULL; |
| char *dstAddr = NULL; |
| int planeDiver = 1; |
| |
| for (int plane = 0; plane < 2; plane++) { |
| planeDiver = (plane + 1) * 2 / 2; |
| |
| srcAddr = previewBuf.virt.extP[plane] + (ALIGN_UP(hwPreviewW, CAMERA_ISP_ALIGN) * dst_crop_height / planeDiver); |
| dstAddr = callbackBuf->virt.extP[plane] + (m_orgPreviewRect.w * dst_crop_height / planeDiver); |
| |
| for (int i = 0; i < remainedH; i++) { |
| memcpy(dstAddr, srcAddr, (m_orgPreviewRect.w / planeDiver)); |
| |
| srcAddr += (ALIGN_UP(hwPreviewW, CAMERA_ISP_ALIGN) / planeDiver); |
| dstAddr += (m_orgPreviewRect.w / planeDiver); |
| } |
| } |
| } |
| #endif |
| } else { /* neon memcpy */ |
| char *srcAddr = NULL; |
| char *dstAddr = NULL; |
| int planeCount = getYuvPlaneCount(hwPreviewFormat); |
| if (planeCount <= 0) { |
| CLOGE("ERR(%s[%d]):getYuvPlaneCount(%d) fail", __FUNCTION__, __LINE__, hwPreviewFormat); |
| statusRet = INVALID_OPERATION; |
| goto done; |
| } |
| |
| /* TODO : have to consider all fmt(planes) and stride */ |
| for (int plane = 0; plane < planeCount; plane++) { |
| srcAddr = previewBuf.addr[plane]; |
| dstAddr = callbackBuf.addr[plane]; |
| memcpy(dstAddr, srcAddr, callbackBuf.size[plane]); |
| } |
| } |
| |
| probeTimer.start(); |
| if (m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME) && |
| !checkBit(&m_callbackState, CALLBACK_STATE_COMPRESSED_IMAGE) && |
| m_disablePreviewCB == false) { |
| if(m_exynosCameraParameters->getVRMode() == 1) { |
| #ifdef SAMSUNG_TIMESTAMP_BOOT |
| setBit(&m_callbackState, CALLBACK_STATE_PREVIEW_FRAME, false); |
| m_dataCb(CAMERA_MSG_PREVIEW_FRAME|CAMERA_MSG_PREVIEW_METADATA, previewCallbackHeap, 0, &m_Metadata, m_callbackCookie); |
| clearBit(&m_callbackState, CALLBACK_STATE_PREVIEW_FRAME, false); |
| #endif |
| } else { |
| setBit(&m_callbackState, CALLBACK_STATE_PREVIEW_FRAME, false); |
| m_dataCb(CAMERA_MSG_PREVIEW_FRAME, previewCallbackHeap, 0, NULL, m_callbackCookie); |
| clearBit(&m_callbackState, CALLBACK_STATE_PREVIEW_FRAME, false); |
| } |
| } |
| probeTimer.stop(); |
| getStreamFrameCount((struct camera2_stream *)previewBuf.addr[2], &fcount); |
| probeTimeMSEC = (int)probeTimer.durationMsecs(); |
| |
| if (probeTimeMSEC > 33 && probeTimeMSEC <= 66) |
| CLOGV("(%s[%d]):(%d) duration time(%5d msec)", __FUNCTION__, __LINE__, fcount, (int)probeTimer.durationMsecs()); |
| else if(probeTimeMSEC > 66) |
| CLOGD("(%s[%d]):(%d) duration time(%5d msec)", __FUNCTION__, __LINE__, fcount, (int)probeTimer.durationMsecs()); |
| else |
| CLOGV("(%s[%d]):(%d) duration time(%5d msec)", __FUNCTION__, __LINE__, fcount, (int)probeTimer.durationMsecs()); |
| |
| done: |
| if (previewCallbackHeap != NULL) { |
| previewCallbackHeap->release(previewCallbackHeap); |
| } |
| |
| return statusRet; |
| } |
| |
| status_t ExynosCamera::m_doCallbackToPreviewFunc( |
| __unused int32_t pipeId, |
| __unused ExynosCameraFrame *newFrame, |
| ExynosCameraBuffer callbackBuf, |
| ExynosCameraBuffer previewBuf) |
| { |
| CLOGV("DEBUG(%s): converting callback to preview buffer", __FUNCTION__); |
| |
| int ret = 0; |
| status_t statusRet = NO_ERROR; |
| |
| int hwPreviewW = 0, hwPreviewH = 0; |
| int hwPreviewFormat = m_exynosCameraParameters->getHwPreviewFormat(); |
| bool useCSC = m_exynosCameraParameters->getCallbackNeedCSC(); |
| |
| m_exynosCameraParameters->getHwPreviewSize(&hwPreviewW, &hwPreviewH); |
| |
| #ifdef SUPPORT_SW_VDIS |
| if(m_swVDIS_Mode) |
| m_swVDIS_AdjustPreviewSize(&hwPreviewW, &hwPreviewH); |
| #endif /*SUPPORT_SW_VDIS*/ |
| |
| camera_memory_t *previewCallbackHeap = NULL; |
| previewCallbackHeap = m_getMemoryCb(callbackBuf.fd[0], callbackBuf.size[0], 1, m_callbackCookie); |
| if (!previewCallbackHeap || previewCallbackHeap->data == MAP_FAILED) { |
| CLOGE("ERR(%s[%d]):m_getMemoryCb(%d) fail", __FUNCTION__, __LINE__, callbackBuf.size[0]); |
| statusRet = INVALID_OPERATION; |
| goto done; |
| } |
| |
| ret = m_setCallbackBufferInfo(&callbackBuf, (char *)previewCallbackHeap->data); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): setCallbackBufferInfo fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| statusRet = INVALID_OPERATION; |
| goto done; |
| } |
| |
| if (m_flagThreadStop == true || m_previewEnabled == false) { |
| CLOGE("ERR(%s[%d]): preview was stopped!", __FUNCTION__, __LINE__); |
| statusRet = INVALID_OPERATION; |
| goto done; |
| } |
| |
| if (useCSC) { |
| #if 0 |
| if (m_exynosPreviewCSC) { |
| csc_set_src_format(m_exynosPreviewCSC, |
| ALIGN_DOWN(m_orgPreviewRect.w, CAMERA_MAGIC_ALIGN), ALIGN_DOWN(m_orgPreviewRect.h, CAMERA_MAGIC_ALIGN), |
| 0, 0, ALIGN_DOWN(m_orgPreviewRect.w, CAMERA_MAGIC_ALIGN), ALIGN_DOWN(m_orgPreviewRect.h, CAMERA_MAGIC_ALIGN), |
| V4L2_PIX_2_HAL_PIXEL_FORMAT(m_orgPreviewRect.colorFormat), |
| 1); |
| |
| csc_set_dst_format(m_exynosPreviewCSC, |
| previewW, previewH, |
| 0, 0, previewW, previewH, |
| V4L2_PIX_2_HAL_PIXEL_FORMAT(previewFormat), |
| 0); |
| |
| csc_set_src_buffer(m_exynosPreviewCSC, |
| (void **)callbackBuf->virt.extP, CSC_MEMORY_USERPTR); |
| |
| csc_set_dst_buffer(m_exynosPreviewCSC, |
| (void **)previewBuf.fd.extFd, CSC_MEMORY_TYPE); |
| |
| if (csc_convert_with_rotation(m_exynosPreviewCSC, 0, m_flip_horizontal, 0) != 0) |
| CLOGE("ERR(%s):csc_convert() from callback to lcd fail", __FUNCTION__); |
| } else { |
| CLOGE("ERR(%s):m_exynosPreviewCSC == NULL", __FUNCTION__); |
| } |
| #else |
| CLOGW("WRN(%s[%d]): doCallbackToPreview use CSC is not yet possible", __FUNCTION__, __LINE__); |
| #endif |
| } else { /* neon memcpy */ |
| char *srcAddr = NULL; |
| char *dstAddr = NULL; |
| int planeCount = getYuvPlaneCount(hwPreviewFormat); |
| if (planeCount <= 0) { |
| CLOGE("ERR(%s[%d]):getYuvPlaneCount(%d) fail", __FUNCTION__, __LINE__, hwPreviewFormat); |
| statusRet = INVALID_OPERATION; |
| goto done; |
| } |
| |
| /* TODO : have to consider all fmt(planes) and stride */ |
| for (int plane = 0; plane < planeCount; plane++) { |
| srcAddr = callbackBuf.addr[plane]; |
| dstAddr = previewBuf.addr[plane]; |
| memcpy(dstAddr, srcAddr, callbackBuf.size[plane]); |
| |
| if (mIonClient >= 0) |
| ion_sync_fd(mIonClient, previewBuf.fd[plane]); |
| } |
| } |
| |
| done: |
| if (previewCallbackHeap != NULL) { |
| previewCallbackHeap->release(previewCallbackHeap); |
| } |
| |
| return statusRet; |
| } |
| |
| status_t ExynosCamera::m_handlePreviewFrameFront(ExynosCameraFrame *frame) |
| { |
| int ret = 0; |
| uint32_t skipCount = 0; |
| ExynosCameraFrameEntity *entity = NULL; |
| ExynosCameraFrame *newFrame = NULL; |
| ExynosCameraFrame *fdFrame = NULL; |
| ExynosCameraBuffer buffer; |
| int pipeID = 0; |
| ExynosCameraBuffer resultBuffer; |
| camera2_node_group node_group_info_isp; |
| enum pipeline pipe; |
| |
| entity = frame->getFrameDoneEntity(); |
| if (entity == NULL) { |
| CLOGE("ERR(%s[%d]):current entity is NULL, frameCount(%d)", |
| __FUNCTION__, __LINE__, frame->getFrameCount()); |
| /* TODO: doing exception handling */ |
| return true; |
| } |
| |
| if (entity->getEntityState() == ENTITY_STATE_FRAME_SKIP) |
| goto entity_state_complete; |
| |
| pipeID = entity->getPipeId(); |
| |
| switch(entity->getPipeId()) { |
| case PIPE_ISP: |
| m_debugFpsCheck(entity->getPipeId()); |
| ret = frame->getSrcBuffer(entity->getPipeId(), &buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getSrcBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| return ret; |
| } |
| frame->setMetaDataEnable(true); |
| |
| ret = m_putBuffers(m_ispBufferMgr, buffer.index); |
| |
| ret = frame->getSrcBuffer(PIPE_3AA, &buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getSrcBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| return ret; |
| } |
| |
| if (m_exynosCameraParameters->isReprocessing() == true) { |
| ret = m_captureSelector->manageFrameHoldList(frame, pipeID, true); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):manageFrameHoldList fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| } else { |
| /* TODO: This is unusual case, flite buffer and isp buffer */ |
| ret = m_putBuffers(m_bayerBufferMgr, buffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):put Buffer fail", __FUNCTION__, __LINE__); |
| } |
| } |
| |
| skipCount = m_exynosCameraParameters->getFrameSkipCount(); |
| if (skipCount <= 0) { |
| /* Face detection */ |
| fdFrame = m_frameMgr->createFrame(m_exynosCameraParameters, frame->getFrameCount()); |
| m_copyMetaFrameToFrame(frame, fdFrame, true, false); |
| m_facedetectQ->pushProcessQ(&fdFrame); |
| } |
| |
| ret = generateFrame(m_3aa_ispFrameCount, &newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):generateFrame fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| m_setupEntity(PIPE_FLITE, newFrame); |
| m_setupEntity(PIPE_3AA, newFrame); |
| m_setupEntity(PIPE_ISP, newFrame); |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, PIPE_ISP); |
| m_previewFrameFactory->pushFrameToPipe(&newFrame, PIPE_FLITE); |
| |
| m_3aa_ispFrameCount++; |
| |
| /* HACK: When SCC pipe is stopped, generate frame for SCC */ |
| if ((m_sccBufferMgr->getNumOfAvailableBuffer() > 2)) { |
| CLOGW("WRN(%s[%d]): Too many available SCC buffers, generating frame for SCC", __FUNCTION__, __LINE__); |
| |
| pipe = (isOwnScc(getCameraId()) == true) ? PIPE_SCC : PIPE_ISPC; |
| |
| while (m_sccBufferMgr->getNumOfAvailableBuffer() > 0) { |
| ret = generateFrame(m_sccFrameCount, &newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):generateFrame fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| m_setupEntity(pipe, newFrame); |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, pipe); |
| m_previewFrameFactory->pushFrameToPipe(&newFrame, pipe); |
| |
| m_sccFrameCount++; |
| } |
| } |
| |
| break; |
| case PIPE_ISPC: |
| case PIPE_SCC: |
| m_debugFpsCheck(entity->getPipeId()); |
| if (entity->getDstBufState() == ENTITY_BUFFER_STATE_COMPLETE) { |
| ret = m_sccCaptureSelector->manageFrameHoldList(frame, entity->getPipeId(), false); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):manageFrameHoldList fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| } |
| |
| pipe = (isOwnScc(getCameraId()) == true) ? PIPE_SCC : PIPE_ISPC; |
| |
| while (m_sccBufferMgr->getNumOfAvailableBuffer() > 0) { |
| ret = generateFrameSccScp(pipe, &m_sccFrameCount, &newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):generateFrameSccScp fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| m_setupEntity(pipe, newFrame); |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, pipe); |
| m_previewFrameFactory->pushFrameToPipe(&newFrame, pipe); |
| |
| m_sccFrameCount++; |
| } |
| break; |
| case PIPE_SCP: |
| if (entity->getDstBufState() == ENTITY_BUFFER_STATE_ERROR) { |
| ret = frame->getDstBuffer(entity->getPipeId(), &buffer, m_previewFrameFactory->getNodeType(PIPE_SCP)); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| return ret; |
| } |
| ret = m_scpBufferMgr->cancelBuffer(buffer.index); |
| |
| } else if (entity->getDstBufState() == ENTITY_BUFFER_STATE_COMPLETE) { |
| m_debugFpsCheck(entity->getPipeId()); |
| ret = frame->getDstBuffer(entity->getPipeId(), &buffer, m_previewFrameFactory->getNodeType(PIPE_SCP)); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| return ret; |
| } |
| |
| m_exynosCameraParameters->getFrameSkipCount(&m_frameSkipCount); |
| if (m_frameSkipCount > 0) { |
| CLOGD("INFO(%s[%d]):frameSkipCount=%d", __FUNCTION__, __LINE__, m_frameSkipCount); |
| ret = m_scpBufferMgr->cancelBuffer(buffer.index); |
| } else { |
| nsecs_t timeStamp = (nsecs_t)frame->getTimeStamp(); |
| if (m_getRecordingEnabled() == true |
| && m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_VIDEO_FRAME)) { |
| if (timeStamp <= 0L) { |
| CLOGE("WARN(%s[%d]):timeStamp(%lld) Skip", __FUNCTION__, __LINE__, (long long)timeStamp); |
| } else { |
| /* get Recording Image buffer */ |
| int bufIndex = -2; |
| ExynosCameraBuffer recordingBuffer; |
| ret = m_recordingBufferMgr->getBuffer(&bufIndex, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL, &recordingBuffer); |
| if (ret < 0 || bufIndex < 0) { |
| if ((++m_recordingFrameSkipCount % 100) == 0) { |
| CLOGE("ERR(%s[%d]): Recording buffer is not available!! Recording Frames are Skipping(%d frames) (bufIndex=%d)", |
| __FUNCTION__, __LINE__, m_recordingFrameSkipCount, bufIndex); |
| } |
| } else { |
| if (m_recordingFrameSkipCount != 0) { |
| CLOGE("ERR(%s[%d]): Recording buffer is not available!! Recording Frames are Skipped(%d frames) (bufIndex=%d)", |
| __FUNCTION__, __LINE__, m_recordingFrameSkipCount, bufIndex); |
| m_recordingFrameSkipCount = 0; |
| } |
| |
| ret = m_doPrviewToRecordingFunc(PIPE_GSC_VIDEO, buffer, recordingBuffer, timeStamp); |
| if (ret < 0) { |
| CLOGW("WARN(%s[%d]):recordingCallback Skip", __FUNCTION__, __LINE__); |
| } |
| } |
| } |
| } |
| |
| ExynosCameraBuffer callbackBuffer; |
| ExynosCameraFrame *callbackFrame = NULL; |
| |
| callbackFrame = m_previewFrameFactory->createNewFrameOnlyOnePipe(PIPE_SCP); |
| frame->getDstBuffer(PIPE_SCP, &callbackBuffer, m_previewFrameFactory->getNodeType(PIPE_SCP)); |
| m_copyMetaFrameToFrame(frame, callbackFrame, true, true); |
| callbackFrame->setDstBuffer(PIPE_SCP, callbackBuffer); |
| |
| CLOGV("INFO(%s[%d]):push frame to front previewQ", __FUNCTION__, __LINE__); |
| m_previewQ->pushProcessQ(&callbackFrame); |
| |
| CLOGV("DEBUG(%s[%d]):SCP done HAL-frameCount(%d)", __FUNCTION__, __LINE__, frame->getFrameCount()); |
| } |
| } else { |
| CLOGV("DEBUG(%s[%d]):SCP droped - SCP buffer is not ready HAL-frameCount(%d)", __FUNCTION__, __LINE__, frame->getFrameCount()); |
| |
| ret = frame->getDstBuffer(entity->getPipeId(), &buffer, m_previewFrameFactory->getNodeType(PIPE_SCP)); |
| if (buffer.index >= 0) { |
| ret = m_scpBufferMgr->cancelBuffer(buffer.index); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):SCP buffer return fail", __FUNCTION__, __LINE__); |
| } |
| m_previewFrameFactory->dump(); |
| } |
| |
| ret = generateFrameSccScp(PIPE_SCP, &m_scpFrameCount, &newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):generateFrameSccScp fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| m_setupEntity(PIPE_SCP, newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail", __FUNCTION__, __LINE__); |
| break; |
| } |
| |
| /*check preview drop...*/ |
| newFrame->getDstBuffer(PIPE_SCP, &resultBuffer, m_previewFrameFactory->getNodeType(PIPE_SCP)); |
| if (resultBuffer.index < 0) { |
| newFrame->setRequest(PIPE_SCP, false); |
| newFrame->getNodeGroupInfo(&node_group_info_isp, PERFRAME_INFO_ISP); |
| node_group_info_isp.capture[PERFRAME_FRONT_SCP_POS].request = 0; |
| newFrame->storeNodeGroupInfo(&node_group_info_isp, PERFRAME_INFO_ISP); |
| |
| m_previewFrameFactory->dump(); |
| |
| /* when preview buffer is not ready, we should drop preview to make preview buffer ready */ |
| CLOGW("WARN(%s[%d]):Front preview drop. Failed to get preview buffer. FrameSkipcount(%d)", |
| __FUNCTION__, __LINE__, FRAME_SKIP_COUNT_PREVIEW_FRONT); |
| m_exynosCameraParameters->setFrameSkipCount(FRAME_SKIP_COUNT_PREVIEW_FRONT); |
| } |
| |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, PIPE_SCP); |
| m_previewFrameFactory->pushFrameToPipe(&newFrame, PIPE_SCP); |
| |
| m_scpFrameCount++; |
| break; |
| default: |
| break; |
| } |
| |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):put Buffer fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| entity_state_complete: |
| |
| ret = frame->setEntityState(entity->getPipeId(), ENTITY_STATE_COMPLETE); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setEntityState fail, pipeId(%d), state(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ENTITY_STATE_COMPLETE, ret); |
| return ret; |
| } |
| |
| if (frame->isComplete() == true) { |
| ret = m_removeFrameFromList(&m_processList, frame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):remove frame from processList fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| |
| frame->decRef(); |
| m_frameMgr->deleteFrame(frame); |
| } |
| |
| return NO_ERROR; |
| } |
| |
| bool ExynosCamera::m_zoomPreviwWithCscThreadFunc(void) |
| { |
| #ifdef DEBUG |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| #endif |
| int ret = 0; |
| bool loop = true; |
| int32_t previewFormat = 0; |
| ExynosRect srcRect, dstRect; |
| ExynosCameraBuffer srcBuf; |
| ExynosCameraBuffer dstBuf; |
| uint32_t *output = NULL; |
| struct camera2_stream *meta = NULL; |
| ExynosCameraBufferManager *srcBufMgr = NULL; |
| ExynosCameraBufferManager *dstBufMgr = NULL; |
| ExynosCameraFrameEntity *entity = NULL; |
| int previewH, previewW; |
| int bufIndex = -1; |
| int waitCount = 0; |
| int scpNodeIndex = -1; |
| int srcNodeIndex = -1; |
| int srcFmt = -1; |
| int pipeId = -1; |
| int gscPipe = -1; |
| ExynosCameraFrame *frame = NULL; |
| int32_t status = 0; |
| frame_queue_t *pipeFrameDoneQ = NULL; |
| entity_buffer_state_t state = ENTITY_BUFFER_STATE_NOREQ; |
| |
| CLOGV("INFO(%s[%d]):wait zoomPreviwWithCscQThreadFunc", __FUNCTION__, __LINE__); |
| status = m_zoomPreviwWithCscQ->waitAndPopProcessQ(&frame); |
| if (m_flagThreadStop == true) { |
| CLOGI("INFO(%s[%d]):m_flagThreadStop(%d)", __FUNCTION__, __LINE__, m_flagThreadStop); |
| return false; |
| } |
| if (status < 0) { |
| /* TODO: We need to make timeout duration depends on FPS */ |
| if (status == TIMED_OUT) { |
| CLOGW("WARN(%s):wait timeout", __FUNCTION__); |
| } else { |
| CLOGE("ERR(%s):wait and pop fail, ret(%d)", __FUNCTION__, ret); |
| /* TODO: doing exception handling */ |
| } |
| return true; |
| } |
| |
| if (frame == NULL) { |
| CLOGE("ERR(%s[%d]):frame is NULL, retry", __FUNCTION__, __LINE__); |
| return true; |
| } |
| |
| pipeFrameDoneQ = m_pipeFrameDoneQ; |
| |
| previewFormat = m_exynosCameraParameters->getHwPreviewFormat(); |
| m_exynosCameraParameters->getHwPreviewSize(&previewW, &previewH); |
| |
| /* get Scaler src Buffer Node Index*/ |
| if (m_exynosCameraParameters->getDualMode() == true && getCameraId() == CAMERA_ID_FRONT) { |
| pipeId = PIPE_3AA; |
| gscPipe = PIPE_GSC; |
| srcNodeIndex = m_previewFrameFactory->getNodeType(PIPE_ISPC); |
| srcFmt = m_exynosCameraParameters->getHWVdisFormat(); |
| scpNodeIndex = m_previewFrameFactory->getNodeType(PIPE_SCP); |
| srcBufMgr = m_sccBufferMgr; |
| dstBufMgr = m_scpBufferMgr; |
| } else { |
| if (m_exynosCameraParameters->getTpuEnabledMode() == true) { |
| pipeId = PIPE_DIS; |
| } else { |
| pipeId = PIPE_ISP; |
| } |
| gscPipe = PIPE_GSC; |
| srcNodeIndex = m_previewFrameFactory->getNodeType(PIPE_SCP); |
| srcFmt = m_exynosCameraParameters->getHwPreviewFormat(); |
| scpNodeIndex = m_previewFrameFactory->getNodeType(PIPE_SCP); |
| srcBufMgr = m_zoomScalerBufferMgr; |
| dstBufMgr = m_scpBufferMgr; |
| } |
| |
| ret = frame->getDstBufferState(pipeId, &state, srcNodeIndex); |
| if (ret < 0 || state != ENTITY_BUFFER_STATE_COMPLETE) { |
| CLOGE("ERR(%s[%d]):getDstBufferState fail, pipeId(%d), state(%d) frame(%d)",__FUNCTION__, __LINE__, pipeId, state, frame->getFrameCount()); |
| ret = INVALID_OPERATION; |
| goto func_exit; |
| } |
| |
| /* get scaler source buffer */ |
| srcBuf.index = -1; |
| |
| ret = frame->getDstBuffer(pipeId, &srcBuf, srcNodeIndex); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d) frame(%d)",__FUNCTION__, __LINE__, pipeId, ret, frame->getFrameCount()); |
| ret = INVALID_OPERATION; |
| goto func_exit; |
| } |
| |
| /* getMetadata to get buffer size */ |
| meta = (struct camera2_stream*)srcBuf.addr[srcBuf.planeCount-1]; |
| |
| if (meta == NULL) { |
| CLOGE("ERR(%s[%d]):meta is NULL, pipeId(%d), ret(%d) frame(%d)", __FUNCTION__, __LINE__, gscPipe, ret, frame->getFrameCount()); |
| ret = INVALID_OPERATION; |
| goto func_exit; |
| } |
| |
| output = meta->output_crop_region; |
| |
| dstBuf.index = -2; |
| bufIndex = -1; |
| ret = dstBufMgr->getBuffer(&bufIndex, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL, &dstBuf); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):Buffer manager getBuffer fail, frame(%d), ret(%d)", |
| __FUNCTION__, __LINE__, frame->getFrameCount(), ret); |
| goto func_exit; |
| } |
| |
| /* csc and scaling */ |
| srcRect.x = 0; |
| srcRect.y = 0; |
| srcRect.w = output[2]; |
| srcRect.h = output[3]; |
| srcRect.fullW = output[2]; |
| srcRect.fullH = output[3]; |
| srcRect.colorFormat = srcFmt; |
| |
| dstRect.x = 0; |
| dstRect.y = 0; |
| dstRect.w = previewW; |
| dstRect.h = previewH; |
| dstRect.fullW = previewW; |
| dstRect.fullH = previewH; |
| dstRect.colorFormat = previewFormat; |
| |
| if (m_exynosCameraParameters->getDualMode() == true && getCameraId() == CAMERA_ID_FRONT) { |
| /* dual front scenario use 3aa bayer crop */ |
| } else { |
| m_exynosCameraParameters->calcPreviewDzoomCropSize(&srcRect, &dstRect); |
| } |
| |
| |
| ret = frame->setSrcRect(gscPipe, srcRect); |
| ret = frame->setDstRect(gscPipe, dstRect); |
| |
| CLOGV("DEBUG(%s[%d]):do zoomPreviw with CSC : srcBuf(%d) dstBuf(%d) (%d, %d, %d, %d) format(%d) actual(%x) -> (%d, %d, %d, %d) format(%d) actual(%x)", __FUNCTION__, __LINE__, srcBuf.index, dstBuf.index, srcRect.x, srcRect.y, srcRect.w, srcRect.h, srcFmt, V4L2_PIX_2_HAL_PIXEL_FORMAT(srcFmt), dstRect.x, dstRect.y, dstRect.w, dstRect.h, previewFormat, V4L2_PIX_2_HAL_PIXEL_FORMAT(previewFormat)); |
| |
| ret = m_setupEntity(gscPipe, frame, &srcBuf, &dstBuf); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail, pipeId(%d), ret(%d) frame(%d)", __FUNCTION__, __LINE__, gscPipe, ret, frame->getFrameCount()); |
| ret = INVALID_OPERATION; |
| goto func_exit; |
| } |
| |
| m_previewFrameFactory->setOutputFrameQToPipe(pipeFrameDoneQ, gscPipe); |
| m_previewFrameFactory->pushFrameToPipe(&frame, gscPipe); |
| |
| CLOGV("DEBUG(%s[%d]):--OUT--", __FUNCTION__, __LINE__); |
| |
| return loop; |
| |
| func_exit: |
| |
| CLOGE("ERR(%s[%d]):do zoomPreviw with CSC failed frame(%d) ret(%d) src(%d) dst(%d)", __FUNCTION__, __LINE__, frame->getFrameCount(), ret, srcBuf.index, dstBuf.index); |
| |
| dstBuf.index = -1; |
| |
| ret = frame->getDstBuffer(gscPipe, &dstBuf); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d) frame(%d)",__FUNCTION__, __LINE__, gscPipe, ret, frame->getFrameCount()); |
| } |
| |
| if (dstBuf.index >= 0) |
| dstBufMgr->cancelBuffer(dstBuf.index); |
| |
| /* msc with ndone frame, in order to frame order*/ |
| CLOGE("ERR(%s[%d]): zoom with scaler getbuffer failed , use MSC for NDONE frame(%d)", __FUNCTION__, __LINE__, frame->getFrameCount()); |
| |
| frame->setSrcBufferState(gscPipe, ENTITY_BUFFER_STATE_ERROR); |
| m_previewFrameFactory->setOutputFrameQToPipe(pipeFrameDoneQ, gscPipe); |
| m_previewFrameFactory->pushFrameToPipe(&frame, gscPipe); |
| |
| CLOGV("DEBUG(%s[%d]):--OUT--", __FUNCTION__, __LINE__); |
| |
| return INVALID_OPERATION; |
| } |
| |
| status_t ExynosCamera::m_syncPrviewWithCSC(int32_t pipeId, int32_t gscPipe, ExynosCameraFrame *frame) |
| { |
| #ifdef DEBUG |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| #endif |
| int32_t previewFormat = 0; |
| status_t ret = NO_ERROR; |
| ExynosRect srcRect, dstRect; |
| ExynosCameraBuffer srcBuf; |
| ExynosCameraBuffer dstBuf; |
| uint32_t *output = NULL; |
| struct camera2_stream *meta = NULL; |
| ExynosCameraBufferManager *srcBufMgr = NULL; |
| ExynosCameraBufferManager *dstBufMgr = NULL; |
| int previewH, previewW; |
| int bufIndex = -1; |
| int waitCount = 0; |
| int srcNodeIndex = -1; |
| int dstNodeIndex = -1; |
| int scpNodeIndex = -1; |
| int srcFmt = -1; |
| entity_buffer_state_t state = ENTITY_BUFFER_STATE_NOREQ; |
| |
| /* copy metadata src to dst*/ |
| if (m_exynosCameraParameters->getDualMode() == true && getCameraId() == CAMERA_ID_FRONT) { |
| srcNodeIndex = m_previewFrameFactory->getNodeType(PIPE_ISPC); |
| dstNodeIndex = 0; |
| scpNodeIndex = m_previewFrameFactory->getNodeType(PIPE_SCP); |
| srcBufMgr = m_sccBufferMgr; |
| dstBufMgr = m_scpBufferMgr; |
| } else { |
| srcNodeIndex = m_previewFrameFactory->getNodeType(PIPE_SCP); |
| dstNodeIndex = 0; |
| scpNodeIndex = m_previewFrameFactory->getNodeType(PIPE_SCP); |
| srcBufMgr = m_zoomScalerBufferMgr; |
| dstBufMgr = m_scpBufferMgr; |
| } |
| |
| state = ENTITY_BUFFER_STATE_NOREQ; |
| ret = frame->getSrcBufferState(gscPipe, &state); |
| if( ret < 0 || state == ENTITY_BUFFER_STATE_ERROR) { |
| CLOGE("ERR(%s[%d]):getSrcBufferState fail, pipeId(%d), entityState(%d) frame(%d)",__FUNCTION__, __LINE__, gscPipe, state, frame->getFrameCount()); |
| ret = INVALID_OPERATION; |
| goto func_exit; |
| } |
| |
| srcBuf.index = -1; |
| dstBuf.index = -1; |
| |
| ret = frame->getSrcBuffer(gscPipe, &srcBuf); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):getSrcBuffer fail, pipeId(%d), ret(%d) frame(%d)",__FUNCTION__, __LINE__, pipeId, ret, frame->getFrameCount()); |
| ret = INVALID_OPERATION; |
| goto func_exit; |
| } |
| |
| ret = frame->getDstBuffer(gscPipe, &dstBuf, dstNodeIndex); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d) frame(%d)",__FUNCTION__, __LINE__, pipeId, ret, frame->getFrameCount()); |
| ret = INVALID_OPERATION; |
| goto func_exit; |
| } |
| |
| memcpy(dstBuf.addr[dstBuf.planeCount-1],srcBuf.addr[srcBuf.planeCount-1], sizeof(struct camera2_stream)); |
| |
| if (m_exynosCameraParameters->getDualMode() == true && getCameraId() == CAMERA_ID_FRONT) { |
| /* dual front scenario use ispc buffer for capture, frameSelector ownership for buffer */ |
| } else { |
| if (srcBuf.index >= 0 ) |
| srcBufMgr->cancelBuffer(srcBuf.index); |
| } |
| |
| ret = frame->setDstBufferState(pipeId, ENTITY_BUFFER_STATE_REQUESTED, scpNodeIndex); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):setDstBufferState fail, pipeId(%d), ret(%d) frame(%d)", |
| __FUNCTION__, __LINE__, pipeId, ret, frame->getFrameCount()); |
| } |
| ret = frame->setDstBuffer(pipeId, dstBuf, scpNodeIndex); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setdst Buffer failed(%d) frame(%d)", __FUNCTION__, __LINE__, ret, frame->getFrameCount()); |
| ret = INVALID_OPERATION; |
| goto func_exit; |
| } |
| ret = frame->setDstBufferState(pipeId, ENTITY_BUFFER_STATE_COMPLETE, scpNodeIndex); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):setDstBufferState fail, pipeId(%d), ret(%d) frame(%d)", |
| __FUNCTION__, __LINE__, pipeId, ret, frame->getFrameCount()); |
| } |
| ret = frame->setDstBufferState(pipeId, ENTITY_BUFFER_STATE_COMPLETE); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):setDstBufferState fail, pipeId(%d), ret(%d) frame(%d)", |
| __FUNCTION__, __LINE__, pipeId, ret, frame->getFrameCount()); |
| } |
| |
| CLOGV("DEBUG(%s[%d]): syncPrviewWithCSC done(%d)", __FUNCTION__, __LINE__, ret); |
| |
| return ret; |
| |
| func_exit: |
| |
| CLOGE("ERR(%s[%d]): sync with csc failed frame(%d) ret(%d) src(%d) dst(%d)", |
| __FUNCTION__, __LINE__, frame->getFrameCount(), ret, srcBuf.index, dstBuf.index); |
| |
| srcBuf.index = -1; |
| dstBuf.index = -1; |
| |
| /* 1. return buffer pipe done. */ |
| ret = frame->getDstBuffer(pipeId, &srcBuf, srcNodeIndex); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):getSrcBuffer fail, pipeId(%d), ret(%d) frame(%d)", |
| __FUNCTION__, __LINE__, pipeId, ret, frame->getFrameCount()); |
| } |
| |
| /* 2. do not return buffer dual front case, frameselector ownershipt for the buffer */ |
| if (m_exynosCameraParameters->getDualMode() == true && getCameraId() == CAMERA_ID_FRONT) { |
| /* dual front scenario use ispc buffer for capture, frameSelector ownership for buffer */ |
| } else { |
| if (srcBuf.index >= 0) |
| srcBufMgr->cancelBuffer(srcBuf.index); |
| } |
| |
| /* 3. if the gsc dst buffer available, return the buffer. */ |
| ret = frame->getDstBuffer(gscPipe, &dstBuf, dstNodeIndex); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d) frame(%d)", |
| __FUNCTION__, __LINE__, pipeId, ret, frame->getFrameCount()); |
| } |
| |
| if (dstBuf.index >= 0) |
| dstBufMgr->cancelBuffer(dstBuf.index); |
| |
| /* 4. change buffer state error for error handlering */ |
| /* 1)dst buffer state : 0( putbuffer ndone for mcpipe ) */ |
| /* 2)dst buffer state : scp node index ( getbuffer ndone for mcpipe ) */ |
| ret = frame->setDstBufferState(pipeId, ENTITY_BUFFER_STATE_ERROR, scpNodeIndex); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):setDstBufferState fail, pipeId(%d), ret(%d) frame(%d)", |
| __FUNCTION__, __LINE__, pipeId, ret, frame->getFrameCount()); |
| } |
| ret = frame->setDstBufferState(pipeId, ENTITY_BUFFER_STATE_ERROR); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):setDstBufferState fail, pipeId(%d), ret(%d) frame(%d)", |
| __FUNCTION__, __LINE__, pipeId, ret, frame->getFrameCount()); |
| } |
| |
| return INVALID_OPERATION; |
| } |
| |
| bool ExynosCamera::m_setBuffersThreadFunc(void) |
| { |
| int ret = 0; |
| |
| ret = m_setBuffers(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_setBuffers failed, releaseBuffer", __FUNCTION__, __LINE__); |
| |
| /* TODO: Need release buffers and error exit */ |
| |
| m_releaseBuffers(); |
| m_isSuccessedBufferAllocation = false; |
| return false; |
| } |
| |
| m_isSuccessedBufferAllocation = true; |
| return false; |
| } |
| |
| bool ExynosCamera::m_startPictureInternalThreadFunc(void) |
| { |
| int ret = 0; |
| |
| ret = m_startPictureInternal(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_setBuffers failed", __FUNCTION__, __LINE__); |
| |
| /* TODO: Need release buffers and error exit */ |
| |
| return false; |
| } |
| |
| return false; |
| } |
| |
| bool ExynosCamera::m_prePictureThreadFunc(void) |
| { |
| bool loop = false; |
| bool isProcessed = true; |
| |
| ExynosCameraDurationTimer m_burstPrePictureTimer; |
| uint64_t m_burstPrePictureTimerTime; |
| uint64_t burstWaitingTime; |
| |
| status_t ret = NO_ERROR; |
| |
| uint64_t seriesShotDuration = m_exynosCameraParameters->getSeriesShotDuration(); |
| |
| m_burstPrePictureTimer.start(); |
| |
| if (m_exynosCameraParameters->isReprocessing()) |
| loop = m_reprocessingPrePictureInternal(); |
| else |
| loop = m_prePictureInternal(&isProcessed); |
| |
| m_burstPrePictureTimer.stop(); |
| m_burstPrePictureTimerTime = m_burstPrePictureTimer.durationUsecs(); |
| |
| if(isProcessed && loop && seriesShotDuration > 0 && m_burstPrePictureTimerTime < seriesShotDuration) { |
| CLOGD("DEBUG(%s[%d]): The time between shots is too short(%lld)us. Extended to (%lld)us" |
| , __FUNCTION__, __LINE__, (long long)m_burstPrePictureTimerTime, (long long)seriesShotDuration); |
| |
| burstWaitingTime = seriesShotDuration - m_burstPrePictureTimerTime; |
| usleep(burstWaitingTime); |
| } |
| |
| return loop; |
| } |
| |
| /* |
| * pIsProcessed : out parameter |
| * true if the frame is properly handled. |
| * false if frame processing is failed or there is no frame to process |
| */ |
| bool ExynosCamera::m_prePictureInternal(bool* pIsProcessed) |
| { |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| CLOGI("DEBUG(%s[%d]):", __FUNCTION__, __LINE__); |
| |
| int ret = 0; |
| bool loop = false; |
| ExynosCameraFrame *newFrame = NULL; |
| camera2_shot_ext *shot_ext = NULL; |
| |
| ExynosCameraBuffer fliteReprocessingBuffer; |
| ExynosCameraBuffer ispReprocessingBuffer; |
| |
| int pipeId = 0; |
| int bufPipeId = 0; |
| bool isSrc = false; |
| int retryCount = 3; |
| |
| if (m_hdrEnabled) |
| retryCount = 15; |
| |
| if (isOwnScc(getCameraId()) == true) { |
| bufPipeId = PIPE_SCC; |
| } else { |
| bufPipeId = PIPE_ISPC; |
| } |
| |
| if (m_exynosCameraParameters->is3aaIspOtf() == true) { |
| pipeId = PIPE_3AA; |
| } else { |
| pipeId = PIPE_ISP; |
| } |
| |
| int postProcessQSize = m_postPictureQ->getSizeOfProcessQ(); |
| if (postProcessQSize > 2) { |
| CLOGW("DEBUG(%s[%d]): post picture is delayed(stacked %d frames), skip", __FUNCTION__, __LINE__, postProcessQSize); |
| usleep(WAITING_TIME); |
| goto CLEAN; |
| } |
| |
| newFrame = m_sccCaptureSelector->selectFrames(m_reprocessingCounter.getCount(), pipeId, isSrc, retryCount, m_pictureFrameFactory->getNodeType(bufPipeId)); |
| if (newFrame == NULL) { |
| CLOGE("ERR(%s[%d]):newFrame is NULL", __FUNCTION__, __LINE__); |
| goto CLEAN; |
| } |
| newFrame->frameLock(); |
| |
| CLOGI("DEBUG(%s[%d]):Frame Count (%d)", __FUNCTION__, __LINE__, newFrame->getFrameCount()); |
| |
| m_postProcessList.push_back(newFrame); |
| |
| if ((m_exynosCameraParameters->getHighResolutionCallbackMode() == true) && |
| (m_highResolutionCallbackRunning == true)) { |
| m_highResolutionCallbackQ->pushProcessQ(&newFrame); |
| } else { |
| dstSccReprocessingQ->pushProcessQ(&newFrame); |
| } |
| |
| m_reprocessingCounter.decCount(); |
| |
| CLOGI("INFO(%s[%d]):prePicture complete, remaining count(%d)", __FUNCTION__, __LINE__, m_reprocessingCounter.getCount()); |
| |
| if (m_hdrEnabled) { |
| ExynosCameraActivitySpecialCapture *m_sCaptureMgr; |
| |
| m_sCaptureMgr = m_exynosCameraActivityControl->getSpecialCaptureMgr(); |
| |
| if (m_reprocessingCounter.getCount() == 0) |
| m_sCaptureMgr->setCaptureStep(ExynosCameraActivitySpecialCapture::SCAPTURE_STEP_OFF); |
| } |
| |
| if ((m_exynosCameraParameters->getHighResolutionCallbackMode() == true) && |
| (m_highResolutionCallbackRunning == true)) |
| loop = true; |
| |
| if (m_reprocessingCounter.getCount() > 0) { |
| loop = true; |
| |
| } |
| |
| *pIsProcessed = true; |
| return loop; |
| |
| CLEAN: |
| if (newFrame != NULL) { |
| newFrame->printEntity(); |
| CLOGD("DEBUG(%s[%d]): Picture frame delete(%d)", __FUNCTION__, __LINE__, newFrame->getFrameCount()); |
| newFrame->decRef(); |
| m_frameMgr->deleteFrame(newFrame); |
| newFrame = NULL; |
| } |
| |
| if (m_hdrEnabled) { |
| ExynosCameraActivitySpecialCapture *m_sCaptureMgr; |
| |
| m_sCaptureMgr = m_exynosCameraActivityControl->getSpecialCaptureMgr(); |
| |
| if (m_reprocessingCounter.getCount() == 0) |
| m_sCaptureMgr->setCaptureStep(ExynosCameraActivitySpecialCapture::SCAPTURE_STEP_OFF); |
| } |
| |
| if (m_reprocessingCounter.getCount() > 0) |
| loop = true; |
| |
| CLOGI("INFO(%s[%d]): prePicture fail, remaining count(%d)", __FUNCTION__, __LINE__, m_reprocessingCounter.getCount()); |
| *pIsProcessed = false; // Notify failure |
| return loop; |
| |
| } |
| |
| bool ExynosCamera::m_shutterCallbackThreadFunc(void) |
| { |
| CLOGI("INFO(%s[%d]):", __FUNCTION__, __LINE__); |
| int loop = false; |
| |
| #ifdef OIS_CAPTURE |
| if(m_OISCaptureShutterEnabled) { |
| CLOGD("INFO(%s[%d]):shutter callback wait start", __FUNCTION__, __LINE__); |
| ExynosCameraActivitySpecialCapture *m_sCaptureMgr = m_exynosCameraActivityControl->getSpecialCaptureMgr(); |
| m_sCaptureMgr->waitShutterCallback(); |
| CLOGD("INFO(%s[%d]):fast shutter callback wait end(%d)", __FUNCTION__, __LINE__, m_sCaptureMgr->getOISCaptureFcount()); |
| } |
| #endif |
| |
| if (m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_SHUTTER)) { |
| CLOGI("INFO(%s[%d]): CAMERA_MSG_SHUTTER callback S", __FUNCTION__, __LINE__); |
| #ifdef BURST_CAPTURE |
| m_notifyCb(CAMERA_MSG_SHUTTER, m_exynosCameraParameters->getSeriesShotDuration(), 0, m_callbackCookie); |
| #else |
| m_notifyCb(CAMERA_MSG_SHUTTER, 0, 0, m_callbackCookie); |
| #endif |
| CLOGI("INFO(%s[%d]): CAMERA_MSG_SHUTTER callback E", __FUNCTION__, __LINE__); |
| } |
| |
| #ifdef FLASHED_LLS_CAPTURE |
| if(m_exynosCameraParameters->getSamsungCamera() && m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_LLS) { |
| if (m_exynosCameraParameters->msgTypeEnabled(MULTI_FRAME_SHOT_FLASHED_INFO)) { |
| m_notifyCb(MULTI_FRAME_SHOT_FLASHED_INFO, m_captureSelector->getFlashedLLSCaptureStatus(), 0, m_callbackCookie); |
| CLOGI("INFO(%s[%d]): MULTI_FRAME_SHOT_FLASHED_INFO callback flash(%s)", |
| __FUNCTION__, __LINE__, m_captureSelector->getFlashedLLSCaptureStatus()? "on" : "off"); |
| } |
| } |
| #endif |
| |
| /* one shot */ |
| return loop; |
| } |
| |
| bool ExynosCamera::m_reprocessingPrePictureInternal(void) |
| { |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| CLOGI("DEBUG(%s[%d]):", __FUNCTION__, __LINE__); |
| |
| int ret = 0; |
| bool loop = false; |
| int retry = 0; |
| int retryIsp = 0; |
| ExynosCameraFrame *newFrame = NULL; |
| ExynosCameraFrameEntity *entity = NULL; |
| camera2_shot_ext *shot_ext = NULL; |
| camera2_stream *shot_stream = NULL; |
| uint32_t bayerFrameCount = 0; |
| struct camera2_node_output output_crop_info; |
| |
| ExynosCameraBufferManager *bufferMgr = NULL; |
| |
| int bayerPipeId = 0; |
| int prePictureDonePipeId = 0; |
| enum pipeline pipe; |
| ExynosCameraBuffer bayerBuffer; |
| ExynosCameraBuffer ispReprocessingBuffer; |
| |
| camera2_shot_ext *updateDmShot = new struct camera2_shot_ext; |
| memset(updateDmShot, 0x0, sizeof(struct camera2_shot_ext)); |
| |
| bayerBuffer.index = -2; |
| ispReprocessingBuffer.index = -2; |
| |
| /* |
| * in case of pureBayer and 3aa_isp OTF, buffer will go isp directly |
| */ |
| if (m_exynosCameraParameters->getUsePureBayerReprocessing() == true) { |
| if (m_exynosCameraParameters->isReprocessing3aaIspOTF() == true) |
| prePictureDonePipeId = PIPE_3AA_REPROCESSING; |
| else |
| prePictureDonePipeId = PIPE_ISP_REPROCESSING; |
| } else { |
| prePictureDonePipeId = PIPE_ISP_REPROCESSING; |
| } |
| |
| if (m_exynosCameraParameters->getHighResolutionCallbackMode() == true) { |
| if (m_highResolutionCallbackRunning == true) { |
| /* will be removed */ |
| while (m_skipReprocessing == true) { |
| usleep(WAITING_TIME); |
| if (m_skipReprocessing == false) { |
| CLOGD("DEBUG(%s[%d]:stop skip frame for high resolution preview callback", __FUNCTION__, __LINE__); |
| break; |
| } |
| } |
| } else if (m_highResolutionCallbackRunning == false) { |
| CLOGW("WRN(%s[%d]): m_reprocessingThreadfunc stop for high resolution preview callback", __FUNCTION__, __LINE__); |
| loop = false; |
| goto CLEAN_FRAME; |
| } |
| } |
| |
| #if defined(SAMSUNG_JQ) && defined(ONE_SECOND_BURST_CAPTURE) |
| if (m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_ONE_SECOND_BURST) { |
| CLOGD("[JQ](%s[%d]): ON!!", __FUNCTION__, __LINE__); |
| m_isJpegQtableOn = true; |
| m_exynosCameraParameters->setJpegQtableOn(true); |
| } |
| #endif |
| |
| if (m_isZSLCaptureOn |
| #ifdef OIS_CAPTURE |
| || m_OISCaptureShutterEnabled |
| #endif |
| ) { |
| CLOGD("INFO(%s[%d]):fast shutter callback!!", __FUNCTION__, __LINE__); |
| m_shutterCallbackThread->join(); |
| m_shutterCallbackThread->run(); |
| } |
| |
| if (m_exynosCameraParameters->getReprocessingBayerMode() == REPROCESSING_BAYER_MODE_PURE_ALWAYS_ON || |
| m_exynosCameraParameters->getReprocessingBayerMode() == REPROCESSING_BAYER_MODE_PURE_DYNAMIC) { |
| /* Get Bayer buffer for reprocessing */ |
| ret = m_getBayerBuffer(m_getBayerPipeId(), &bayerBuffer); |
| } else if (m_exynosCameraParameters->getReprocessingBayerMode() == REPROCESSING_BAYER_MODE_DIRTY_ALWAYS_ON || |
| m_exynosCameraParameters->getReprocessingBayerMode() == REPROCESSING_BAYER_MODE_DIRTY_DYNAMIC) { |
| /* Get Bayer buffer for reprocessing */ |
| ret = m_getBayerBuffer(m_getBayerPipeId(), &bayerBuffer, updateDmShot); |
| } else { |
| CLOGE("ERR(%s[%d]): bayer mode is not valid (%d)", __FUNCTION__, __LINE__, |
| m_exynosCameraParameters->getReprocessingBayerMode()); |
| goto CLEAN_FRAME; |
| } |
| |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): getBayerBuffer fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto CLEAN_FRAME; |
| } |
| |
| if (bayerBuffer.index == -2) { |
| CLOGE("ERR(%s[%d]): getBayerBuffer fail. buffer index is -2", __FUNCTION__, __LINE__); |
| goto CLEAN_FRAME; |
| } |
| |
| if (m_exynosCameraParameters->getCaptureExposureTime() != 0 && m_stopLongExposure) { |
| CLOGD("DEBUG(%s[%d]): Emergency stop", __FUNCTION__, __LINE__); |
| goto CLEAN_FRAME; |
| } |
| |
| #ifdef SAMSUNG_LBP |
| if (m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_NONE && m_isLBPon == true) { |
| ret = m_captureSelector->setFrameHoldCount(REPROCESSING_BAYER_HOLD_COUNT); |
| m_LBPThread->requestExitAndWait(); |
| m_lbpBufferMgr->resetBuffers(); |
| if(m_LBPpluginHandle != NULL) { |
| ret = uni_plugin_deinit(m_LBPpluginHandle); |
| if(ret < 0) |
| CLOGE("[LBP](%s[%d]):Bestphoto plugin deinit failed!!", __FUNCTION__, __LINE__); |
| } |
| m_LBPindex = 0; |
| m_isLBPon = false; |
| } |
| #endif |
| |
| #ifdef SAMSUNG_DEBLUR |
| if(m_exynosCameraParameters->getLDCaptureMode() == MULTI_SHOT_MODE_DEBLUR |
| && m_reprocessingCounter.getCount() == 1) { |
| CLOGD("DEBUG(%s[%d]):m_reprocessingCounter.getCount()(%d)", __FUNCTION__, __LINE__, m_reprocessingCounter.getCount()); |
| m_exynosCameraParameters->setOISCaptureModeOn(false); |
| ret = m_captureSelector->setFrameHoldCount(1); |
| } |
| #endif |
| |
| CLOGD("DEBUG(%s[%d]):bayerBuffer index %d", __FUNCTION__, __LINE__, bayerBuffer.index); |
| |
| if (m_exynosCameraParameters->getReprocessingBayerMode() == REPROCESSING_BAYER_MODE_DIRTY_DYNAMIC) { |
| m_captureSelector->clearList(m_getBayerPipeId(), false, m_previewFrameFactory->getNodeType(PIPE_3AC)); |
| } |
| |
| if (!m_isZSLCaptureOn |
| #ifdef OIS_CAPTURE |
| && !m_OISCaptureShutterEnabled |
| #endif |
| #ifdef BURST_CAPTURE |
| && (m_exynosCameraParameters->getSeriesShotMode() != SERIES_SHOT_MODE_BURST |
| || m_burstShutterLocation == BURST_SHUTTER_PREPICTURE) |
| #endif |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| && (m_exynosCameraParameters->getSeriesShotMode() != SERIES_SHOT_MODE_ONE_SECOND_BURST |
| || m_burstShutterLocation == BURST_SHUTTER_PREPICTURE) |
| #endif |
| ) { |
| m_shutterCallbackThread->join(); |
| m_shutterCallbackThread->run(); |
| #ifdef BURST_CAPTURE |
| if (m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_BURST) |
| m_burstShutterLocation = BURST_SHUTTER_PREPICTURE_DONE; |
| #endif |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| if (m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_ONE_SECOND_BURST) |
| m_burstShutterLocation = BURST_SHUTTER_PREPICTURE_DONE; |
| #endif |
| } |
| |
| #ifdef OIS_CAPTURE |
| m_OISCaptureShutterEnabled = false; |
| #endif |
| |
| m_isZSLCaptureOn = false; |
| |
| #ifdef OIS_CAPTURE |
| if ((m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_LLS || |
| m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_SIS) && |
| m_reprocessingCounter.getCount() == 1) { |
| CLOGD("DEBUG(%s[%d]):LLS last capture frame", __FUNCTION__, __LINE__); |
| #ifndef LLS_REPROCESSING |
| ExynosCameraActivitySpecialCapture *m_sCaptureMgr = m_exynosCameraActivityControl->getSpecialCaptureMgr(); |
| m_sCaptureMgr->setCaptureStep(ExynosCameraActivitySpecialCapture::SCAPTURE_STEP_WAIT_CAPTURE); |
| #else |
| m_exynosCameraParameters->setOISCaptureModeOn(false); |
| #endif |
| } |
| #endif |
| |
| /* Generate reprocessing Frame */ |
| ret = generateFrameReprocessing(&newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):generateFrameReprocessing fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto CLEAN_FRAME; |
| } |
| |
| #ifndef RAWDUMP_CAPTURE |
| #ifdef DEBUG_RAWDUMP |
| if (m_exynosCameraParameters->checkBayerDumpEnable()) { |
| int sensorMaxW, sensorMaxH; |
| int sensorMarginW, sensorMarginH; |
| bool bRet; |
| char filePath[70]; |
| |
| memset(filePath, 0, sizeof(filePath)); |
| snprintf(filePath, sizeof(filePath), "/data/media/0/RawCapture%d_%d.raw",m_cameraId, m_fliteFrameCount); |
| if (m_exynosCameraParameters->getUsePureBayerReprocessing() == true) { |
| /* Pure Bayer Buffer Size == MaxPictureSize + Sensor Margin == Max Sensor Size */ |
| m_exynosCameraParameters->getMaxSensorSize(&sensorMaxW, &sensorMaxH); |
| } else { |
| m_exynosCameraParameters->getMaxPictureSize(&sensorMaxW, &sensorMaxH); |
| } |
| |
| bRet = dumpToFile((char *)filePath, |
| bayerBuffer.addr[0], |
| sensorMaxW * sensorMaxH * 2); |
| if (bRet != true) |
| CLOGE("couldn't make a raw file"); |
| } |
| #endif /* DEBUG_RAWDUMP */ |
| #endif |
| |
| if (m_exynosCameraParameters->getUsePureBayerReprocessing() == false |
| #ifdef LLS_REPROCESSING |
| && m_captureSelector->getIsConvertingMeta() == true |
| #endif |
| ) { |
| /* TODO: HACK: Will be removed, this is driver's job */ |
| ret = m_convertingStreamToShotExt(&bayerBuffer, &output_crop_info); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): shot_stream to shot_ext converting fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto CLEAN_FRAME; |
| } |
| |
| camera2_node_group node_group_info; |
| ExynosRect srcRect , dstRect; |
| int pictureW = 0, pictureH = 0; |
| |
| memset(&node_group_info, 0x0, sizeof(camera2_node_group)); |
| m_exynosCameraParameters->getPictureSize(&pictureW, &pictureH); |
| |
| newFrame->getNodeGroupInfo(&node_group_info, PERFRAME_INFO_DIRTY_REPROCESSING_ISP); |
| node_group_info.leader.input.cropRegion[0] = output_crop_info.cropRegion[0]; |
| node_group_info.leader.input.cropRegion[1] = output_crop_info.cropRegion[1]; |
| node_group_info.leader.input.cropRegion[2] = output_crop_info.cropRegion[2]; |
| node_group_info.leader.input.cropRegion[3] = output_crop_info.cropRegion[3]; |
| node_group_info.leader.output.cropRegion[0] = 0; |
| node_group_info.leader.output.cropRegion[1] = 0; |
| node_group_info.leader.output.cropRegion[2] = node_group_info.leader.input.cropRegion[2]; |
| node_group_info.leader.output.cropRegion[3] = node_group_info.leader.input.cropRegion[3]; |
| |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].input.cropRegion[0] = node_group_info.leader.output.cropRegion[0]; |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].input.cropRegion[1] = node_group_info.leader.output.cropRegion[1]; |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].input.cropRegion[2] = node_group_info.leader.output.cropRegion[2]; |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].input.cropRegion[3] = node_group_info.leader.output.cropRegion[3]; |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].output.cropRegion[0] = 0; |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].output.cropRegion[1] = 0; |
| if (isOwnScc(getCameraId()) == true) { |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].output.cropRegion[2] = pictureW; |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].output.cropRegion[3] = pictureH; |
| } else { |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].output.cropRegion[2] = node_group_info.leader.output.cropRegion[2]; |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].output.cropRegion[3] = node_group_info.leader.output.cropRegion[3]; |
| } |
| |
| CLOGV("DEBUG(%s[%d]): isp capture input(%d %d %d %d), output(%d %d %d %d)", __FUNCTION__, __LINE__, |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].input.cropRegion[0], |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].input.cropRegion[1], |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].input.cropRegion[2], |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].input.cropRegion[3], |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].output.cropRegion[0], |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].output.cropRegion[1], |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].output.cropRegion[2], |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].output.cropRegion[3]); |
| |
| if (node_group_info.leader.output.cropRegion[2] < node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].input.cropRegion[2]) { |
| CLOGI("INFO(%s[%d]:(%d -> %d))", __FUNCTION__, __LINE__, |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].input.cropRegion[2], |
| node_group_info.leader.output.cropRegion[2]); |
| |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].input.cropRegion[2] = node_group_info.leader.output.cropRegion[2]; |
| } |
| if (node_group_info.leader.output.cropRegion[3] < node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].input.cropRegion[3]) { |
| CLOGI("INFO(%s[%d]:(%d -> %d))", __FUNCTION__, __LINE__, |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].input.cropRegion[3], |
| node_group_info.leader.output.cropRegion[3]); |
| |
| node_group_info.capture[PERFRAME_REPROCESSING_SCC_POS].input.cropRegion[3] = node_group_info.leader.output.cropRegion[3]; |
| } |
| |
| newFrame->storeNodeGroupInfo(&node_group_info, PERFRAME_INFO_DIRTY_REPROCESSING_ISP); |
| } |
| |
| shot_ext = (struct camera2_shot_ext *)(bayerBuffer.addr[1]); |
| |
| /* Meta setting */ |
| if (shot_ext != NULL) { |
| if (m_exynosCameraParameters->getReprocessingBayerMode() == REPROCESSING_BAYER_MODE_PURE_ALWAYS_ON || |
| m_exynosCameraParameters->getReprocessingBayerMode() == REPROCESSING_BAYER_MODE_PURE_DYNAMIC) { |
| ret = newFrame->storeDynamicMeta(shot_ext); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): storeDynamicMeta fail ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto CLEAN_FRAME; |
| } |
| |
| ret = newFrame->storeUserDynamicMeta(shot_ext); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): storeUserDynamicMeta fail ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto CLEAN_FRAME; |
| } |
| } else if (m_exynosCameraParameters->getReprocessingBayerMode() == REPROCESSING_BAYER_MODE_DIRTY_ALWAYS_ON || |
| m_exynosCameraParameters->getReprocessingBayerMode() == REPROCESSING_BAYER_MODE_DIRTY_DYNAMIC) { |
| ret = newFrame->storeDynamicMeta(updateDmShot); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): storeDynamicMeta fail ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto CLEAN_FRAME; |
| } |
| |
| ret = newFrame->storeUserDynamicMeta(updateDmShot); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): storeUserDynamicMeta fail ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto CLEAN_FRAME; |
| } |
| } |
| |
| newFrame->getMetaData(shot_ext); |
| m_exynosCameraParameters->duplicateCtrlMetadata((void *)shot_ext); |
| |
| CLOGD("DEBUG(%s[%d]):meta_shot_ext->shot.dm.request.frameCount : %d", |
| __FUNCTION__, __LINE__, |
| getMetaDmRequestFrameCount(shot_ext)); |
| } else { |
| CLOGE("DEBUG(%s[%d]):shot_ext is NULL", __FUNCTION__, __LINE__); |
| } |
| |
| /* SCC */ |
| if (isOwnScc(getCameraId()) == true) { |
| pipe = PIPE_SCC_REPROCESSING; |
| |
| m_getBufferManager(pipe, &bufferMgr, DST_BUFFER_DIRECTION); |
| |
| ret = m_checkBufferAvailable(pipe, bufferMgr); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): Waiting buffer timeout, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipe, ret); |
| goto CLEAN_FRAME; |
| } |
| |
| ret = m_setupEntity(pipe, newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]:setupEntity fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipe, ret); |
| goto CLEAN_FRAME; |
| } |
| |
| if ((m_exynosCameraParameters->getHighResolutionCallbackMode() == true) && |
| (m_highResolutionCallbackRunning == true)) { |
| m_reprocessingFrameFactory->setOutputFrameQToPipe(m_highResolutionCallbackQ, pipe); |
| } else { |
| m_reprocessingFrameFactory->setOutputFrameQToPipe(dstSccReprocessingQ, pipe); |
| } |
| |
| /* push frame to SCC pipe */ |
| m_reprocessingFrameFactory->pushFrameToPipe(&newFrame, pipe); |
| } else { |
| if (m_exynosCameraParameters->isReprocessing3aaIspOTF() == false) { |
| pipe = PIPE_ISP_REPROCESSING; |
| |
| m_getBufferManager(pipe, &bufferMgr, DST_BUFFER_DIRECTION); |
| |
| ret = m_checkBufferAvailable(pipe, bufferMgr); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): Waiting buffer timeout, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipe, ret); |
| goto CLEAN_FRAME; |
| } |
| |
| } else { |
| pipe = PIPE_3AA_REPROCESSING; |
| } |
| |
| if ((m_exynosCameraParameters->getHighResolutionCallbackMode() == true) && |
| (m_highResolutionCallbackRunning == true)) { |
| m_reprocessingFrameFactory->setFrameDoneQToPipe(m_highResolutionCallbackQ, pipe); |
| } else { |
| m_reprocessingFrameFactory->setFrameDoneQToPipe(dstSccReprocessingQ, pipe); |
| } |
| |
| } |
| |
| /* Add frame to post processing list */ |
| CLOGD("DEBUG(%s[%d]): push frame(%d) to postPictureList", |
| __FUNCTION__, __LINE__, newFrame->getFrameCount()); |
| newFrame->frameLock(); |
| m_postProcessList.push_back(newFrame); |
| |
| ret = m_reprocessingFrameFactory->startInitialThreads(); |
| if (ret < 0) { |
| CLOGE("ERR(%s):startInitialThreads fail", __FUNCTION__); |
| goto CLEAN; |
| } |
| |
| if (isOwnScc(getCameraId()) == true) { |
| retry = 0; |
| do { |
| if( m_reprocessingFrameFactory->checkPipeThreadRunning(pipe) == false ) { |
| ret = m_reprocessingFrameFactory->startInitialThreads(); |
| if (ret < 0) { |
| CLOGE("ERR(%s):startInitialThreads fail", __FUNCTION__); |
| } |
| } |
| |
| ret = newFrame->ensureDstBufferState(pipe, ENTITY_BUFFER_STATE_PROCESSING); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): ensure buffer state(ENTITY_BUFFER_STATE_PROCESSING) fail(retry), ret(%d)", __FUNCTION__, __LINE__, ret); |
| usleep(1000); |
| retry++; |
| } |
| } while (ret < 0 && retry < 100); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): ensure buffer state(ENTITY_BUFFER_STATE_PROCESSING) fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto CLEAN; |
| } |
| } |
| |
| /* Get bayerPipeId at first entity */ |
| bayerPipeId = newFrame->getFirstEntity()->getPipeId(); |
| CLOGD("DEBUG(%s[%d]): bayer Pipe ID(%d)", __FUNCTION__, __LINE__, bayerPipeId); |
| |
| /* Check available buffer */ |
| ret = m_getBufferManager(bayerPipeId, &bufferMgr, DST_BUFFER_DIRECTION); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): getBufferManager fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto CLEAN; |
| } |
| if (bufferMgr != NULL) { |
| ret = m_checkBufferAvailable(bayerPipeId, bufferMgr); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): Waiting buffer timeout, bayerPipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, bayerPipeId, ret); |
| goto CLEAN; |
| } |
| } |
| |
| ret = m_setupEntity(bayerPipeId, newFrame, &bayerBuffer, NULL); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]:setupEntity fail, bayerPipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, bayerPipeId, ret); |
| goto CLEAN; |
| } |
| |
| m_reprocessingFrameFactory->setOutputFrameQToPipe(dstIspReprocessingQ, prePictureDonePipeId); |
| |
| newFrame->incRef(); |
| |
| /* push the newFrameReprocessing to pipe */ |
| m_reprocessingFrameFactory->pushFrameToPipe(&newFrame, bayerPipeId); |
| |
| /* When enabled SCC capture or pureBayerReprocessing, we need to start bayer pipe thread */ |
| if (m_exynosCameraParameters->getUsePureBayerReprocessing() == true || |
| m_exynosCameraParameters->isSccCapture() == true) |
| m_reprocessingFrameFactory->startThread(bayerPipeId); |
| |
| /* wait ISP done */ |
| CLOGI("INFO(%s[%d]):wait ISP output", __FUNCTION__, __LINE__); |
| newFrame = NULL; |
| do { |
| ret = dstIspReprocessingQ->waitAndPopProcessQ(&newFrame); |
| retryIsp++; |
| } while (ret == TIMED_OUT && retryIsp < 200 && m_flagThreadStop != true); |
| |
| if (ret < 0) { |
| CLOGW("WARN(%s[%d]):ISP wait and pop return, ret(%d)", __FUNCTION__, __LINE__, ret); |
| /* TODO: doing exception handling */ |
| /* goto CLEAN; */ |
| } |
| if (newFrame == NULL) { |
| CLOGE("ERR(%s[%d]):newFrame is NULL", __FUNCTION__, __LINE__); |
| goto CLEAN; |
| } |
| |
| bayerBuffer.index = -2; |
| ret = newFrame->getSrcBuffer(bayerPipeId, &bayerBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getSrcBuffer fail, bayerPipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, bayerPipeId, ret); |
| } |
| |
| shot_ext = (struct camera2_shot_ext *)(bayerBuffer.addr[1]); |
| |
| ret = newFrame->setEntityState(bayerPipeId, ENTITY_STATE_COMPLETE); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setEntityState(ENTITY_STATE_PROCESSING) fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, bayerPipeId, ret); |
| |
| if (updateDmShot != NULL) { |
| delete updateDmShot; |
| updateDmShot = NULL; |
| } |
| |
| return ret; |
| } |
| |
| CLOGI("INFO(%s[%d]):ISP output done", __FUNCTION__, __LINE__); |
| |
| newFrame->setMetaDataEnable(true); |
| |
| #ifdef LLS_CAPTURE |
| if (shot_ext != NULL) { |
| if ((m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_LLS || |
| m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_SIS) && |
| m_reprocessingCounter.getCount() == m_exynosCameraParameters->getSeriesShotCount()) { |
| CLOGD("LLS(%s[%d]): lls_tuning_set_index(%d)", __FUNCTION__, __LINE__, shot_ext->shot.dm.stats.vendor_lls_tuning_set_index); |
| CLOGD("LLS(%s[%d]): lls_brightness_index(%d)", __FUNCTION__, __LINE__, shot_ext->shot.dm.stats.vendor_lls_brightness_index); |
| m_notifyCb(MULTI_FRAME_SHOT_PARAMETERS, shot_ext->shot.dm.stats.vendor_lls_tuning_set_index, |
| shot_ext->shot.dm.stats.vendor_lls_brightness_index, m_callbackCookie); |
| } |
| } |
| #endif |
| |
| #ifdef LLS_REPROCESSING |
| if (m_captureSelector->getIsLastFrame() == true) |
| #endif |
| { |
| /* put bayer buffer */ |
| ret = m_putBuffers(m_bayerBufferMgr, bayerBuffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): 3AA src putBuffer fail, index(%d), ret(%d)", __FUNCTION__, __LINE__, bayerBuffer.index, ret); |
| goto CLEAN; |
| } |
| #ifdef LLS_REPROCESSING |
| m_captureSelector->setIsConvertingMeta(true); |
| #endif |
| } |
| |
| /* put isp buffer */ |
| if (m_exynosCameraParameters->getUsePureBayerReprocessing() == true) { |
| ret = m_getBufferManager(bayerPipeId, &bufferMgr, DST_BUFFER_DIRECTION); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): getBufferManager fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto CLEAN; |
| } |
| if (bufferMgr != NULL) { |
| ret = newFrame->getDstBuffer(bayerPipeId, &ispReprocessingBuffer, m_previewFrameFactory->getNodeType(PIPE_FLITE)); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, bayerPipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, bayerPipeId, ret); |
| goto CLEAN; |
| } |
| ret = m_putBuffers(m_ispReprocessingBufferMgr, ispReprocessingBuffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): ISP src putBuffer fail, index(%d), ret(%d)", __FUNCTION__, __LINE__, bayerBuffer.index, ret); |
| goto CLEAN; |
| } |
| } |
| } |
| |
| m_reprocessingCounter.decCount(); |
| |
| CLOGI("INFO(%s[%d]):reprocessing complete, remaining count(%d)", __FUNCTION__, __LINE__, m_reprocessingCounter.getCount()); |
| |
| if (m_hdrEnabled) { |
| ExynosCameraActivitySpecialCapture *m_sCaptureMgr; |
| |
| m_sCaptureMgr = m_exynosCameraActivityControl->getSpecialCaptureMgr(); |
| |
| if (m_reprocessingCounter.getCount() == 0) |
| m_sCaptureMgr->setCaptureStep(ExynosCameraActivitySpecialCapture::SCAPTURE_STEP_OFF); |
| } |
| |
| #ifdef OIS_CAPTURE |
| if (m_exynosCameraParameters->getOISCaptureModeOn() == true && m_reprocessingCounter.getCount() == 0) { |
| m_exynosCameraParameters->setOISCaptureModeOn(false); |
| } |
| #endif |
| |
| if (newFrame != NULL) { |
| CLOGD("DEBUG(%s[%d]): Reprocessing frame delete(%d)", __FUNCTION__, __LINE__, newFrame->getFrameCount()); |
| newFrame->decRef(); |
| m_frameMgr->deleteFrame(newFrame); |
| newFrame = NULL; |
| } |
| if ((m_exynosCameraParameters->getHighResolutionCallbackMode() == true) && |
| (m_highResolutionCallbackRunning == true)) { |
| loop = true; |
| } |
| |
| if (m_reprocessingCounter.getCount() > 0) |
| loop = true; |
| |
| if (updateDmShot != NULL) { |
| delete updateDmShot; |
| updateDmShot = NULL; |
| } |
| |
| /* one shot */ |
| return loop; |
| |
| CLEAN_FRAME: |
| /* newFrame is not pushed any pipes, we can delete newFrame */ |
| if (newFrame != NULL) { |
| newFrame->printEntity(); |
| CLOGD("DEBUG(%s[%d]): Reprocessing frame delete(%d)", __FUNCTION__, __LINE__, newFrame->getFrameCount()); |
| newFrame->decRef(); |
| m_frameMgr->deleteFrame(newFrame); |
| newFrame = NULL; |
| } |
| |
| CLEAN: |
| if (newFrame != NULL) { |
| bayerBuffer.index = -2; |
| ret = m_getBufferManager(bayerPipeId, &bufferMgr, SRC_BUFFER_DIRECTION); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): getBufferManager fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| if (bufferMgr != NULL) { |
| ret = newFrame->getSrcBuffer(bayerPipeId, &bayerBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, bayerPipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, bayerPipeId, ret); |
| } |
| if (bayerBuffer.index >= 0) |
| m_putBuffers(bufferMgr, bayerBuffer.index); |
| } |
| |
| if (m_exynosCameraParameters->getUsePureBayerReprocessing() == true) { |
| ret = m_getBufferManager(bayerPipeId, &bufferMgr, DST_BUFFER_DIRECTION); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): getBufferManager fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| if (bufferMgr != NULL) { |
| ret = newFrame->getDstBuffer(bayerPipeId, &ispReprocessingBuffer, |
| m_pictureFrameFactory->getNodeType(PIPE_3AC)); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, bayerPipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, bayerPipeId, ret); |
| } |
| if (ispReprocessingBuffer.index >= 0) |
| m_putBuffers(bufferMgr, ispReprocessingBuffer.index); |
| } |
| } |
| } |
| |
| /* newFrame is already pushed some pipes, we can not delete newFrame until frame is complete */ |
| if (newFrame != NULL) { |
| newFrame->frameUnlock(); |
| ret = m_removeFrameFromList(&m_postProcessList, newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):remove frame from processList fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| |
| newFrame->printEntity(); |
| CLOGD("DEBUG(%s[%d]): Reprocessing frame delete(%d)", __FUNCTION__, __LINE__, newFrame->getFrameCount()); |
| #ifdef LLS_REPROCESSING |
| if (m_captureSelector->getIsLastFrame() == true) |
| #endif |
| { |
| newFrame->decRef(); |
| m_frameMgr->deleteFrame(newFrame); |
| newFrame = NULL; |
| } |
| } |
| |
| if (updateDmShot != NULL) { |
| delete updateDmShot; |
| updateDmShot = NULL; |
| } |
| |
| if (m_hdrEnabled) { |
| ExynosCameraActivitySpecialCapture *m_sCaptureMgr; |
| |
| m_sCaptureMgr = m_exynosCameraActivityControl->getSpecialCaptureMgr(); |
| |
| if (m_reprocessingCounter.getCount() == 0) |
| m_sCaptureMgr->setCaptureStep(ExynosCameraActivitySpecialCapture::SCAPTURE_STEP_OFF); |
| } |
| |
| #ifdef OIS_CAPTURE |
| if (m_exynosCameraParameters->getOISCaptureModeOn() == true && m_reprocessingCounter.getCount() == 0) { |
| m_exynosCameraParameters->setOISCaptureModeOn(false); |
| } |
| #endif |
| |
| if (newFrame != NULL) { |
| newFrame->decRef(); |
| m_frameMgr->deleteFrame(newFrame); |
| newFrame = NULL; |
| } |
| if ((m_exynosCameraParameters->getHighResolutionCallbackMode() == true) && |
| (m_highResolutionCallbackRunning == true)) { |
| loop = true; |
| } |
| |
| if (m_reprocessingCounter.getCount() > 0) |
| loop = true; |
| |
| CLOGI("INFO(%s[%d]): reprocessing fail, remaining count(%d)", __FUNCTION__, __LINE__, m_reprocessingCounter.getCount()); |
| |
| return loop; |
| } |
| |
| #if defined(SAMSUNG_COMPANION) |
| int ExynosCamera::m_getSensorId(int m_cameraId) |
| { |
| unsigned int scenario = 0; |
| unsigned int scenarioBit = 0; |
| unsigned int nodeNumBit = 0; |
| unsigned int sensorIdBit = 0; |
| unsigned int sensorId = getSensorId(m_cameraId); |
| |
| scenarioBit = (scenario << SCENARIO_SHIFT); |
| |
| nodeNumBit = ((FIMC_IS_VIDEO_SS0_NUM - FIMC_IS_VIDEO_SS0_NUM) << SSX_VINDEX_SHIFT); |
| |
| sensorIdBit = (sensorId << 0); |
| |
| return (scenarioBit) | (nodeNumBit) | (sensorIdBit); |
| } |
| |
| bool ExynosCamera::m_companionThreadFunc(void) |
| { |
| CLOGI("INFO(%s[%d]):", __FUNCTION__, __LINE__); |
| ExynosCameraDurationTimer m_timer; |
| long long durationTime = 0; |
| int loop = false; |
| int ret = 0; |
| |
| m_timer.start(); |
| |
| m_companionNode = new ExynosCameraNode(); |
| |
| ret = m_companionNode->create("companion", m_cameraId); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): Companion Node create fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| |
| ret = m_companionNode->open(MAIN_CAMERA_COMPANION_NUM); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): Companion Node open fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| CLOGD("DEBUG(%s):Companion Node(%d) opened running)", __FUNCTION__, MAIN_CAMERA_COMPANION_NUM); |
| |
| ret = m_companionNode->setInput(m_getSensorId(m_cameraId)); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): Companion Node s_input fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| CLOGD("DEBUG(%s):Companion Node(%d) s_input)", __FUNCTION__, MAIN_CAMERA_COMPANION_NUM); |
| |
| m_timer.stop(); |
| durationTime = m_timer.durationMsecs(); |
| CLOGD("DEBUG(%s):duration time(%5d msec)", __FUNCTION__, (int)durationTime); |
| |
| /* one shot */ |
| return loop; |
| } |
| #endif |
| |
| #if defined(SAMSUNG_EEPROM) |
| bool ExynosCamera::m_eepromThreadFunc(void) |
| { |
| CLOGI("INFO(%s[%d]):", __FUNCTION__, __LINE__); |
| ExynosCameraDurationTimer m_timer; |
| long long durationTime = 0; |
| char sensorFW[50] = {0,}; |
| int ret = 0; |
| FILE *fp = NULL; |
| |
| m_timer.start(); |
| |
| if(m_cameraId == CAMERA_ID_BACK) { |
| fp = fopen(SENSOR_FW_PATH_BACK, "r"); |
| } else { |
| fp = fopen(SENSOR_FW_PATH_FRONT, "r"); |
| } |
| if (fp == NULL) { |
| CLOGE("ERR(%s[%d]):failed to open sysfs. camera id = %d", __FUNCTION__, __LINE__, m_cameraId); |
| goto err; |
| } |
| |
| if (fgets(sensorFW, sizeof(sensorFW), fp) == NULL) { |
| CLOGE("ERR(%s[%d]):failed to read sysfs entry", __FUNCTION__, __LINE__); |
| goto err; |
| } |
| |
| /* int numread = strlen(sensorFW); */ |
| CLOGI("INFO(%s[%d]): eeprom read complete. Sensor FW ver: %s", __FUNCTION__, __LINE__, sensorFW); |
| |
| err: |
| if (fp != NULL) |
| fclose(fp); |
| |
| m_timer.stop(); |
| durationTime = m_timer.durationMsecs(); |
| CLOGD("DEBUG(%s):duration time(%5d msec)", __FUNCTION__, (int)durationTime); |
| |
| /* one shot */ |
| return false; |
| } |
| #endif |
| |
| bool ExynosCamera::m_ThumbnailCallbackThreadFunc(void) |
| { |
| #ifdef DEBUG |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| #endif |
| int32_t previewFormat = 0; |
| status_t ret = NO_ERROR; |
| ExynosRect srcRect, dstRect; |
| int thumbnailH, thumbnailW; |
| int previewH, previewW; |
| int waitCount = 0; |
| int dstbufferIndex = -1; |
| ExynosCameraFrame *callbackFrame = NULL; |
| ExynosCameraBuffer postgscReprocessingSrcBuffer; |
| ExynosCameraBuffer postgscReprocessingDstBuffer; |
| ExynosCameraBufferManager *srcbufferMgr = NULL; |
| ExynosCameraBufferManager *dstbufferMgr = NULL; |
| int gscPipe = PIPE_GSC_REPROCESSING3; |
| int retry = 0; |
| int framecount = 0; |
| int loop = false; |
| |
| postgscReprocessingSrcBuffer.index = -2; |
| postgscReprocessingDstBuffer.index = -2; |
| |
| CLOGD("DEBUG(%s[%d]):-- IN --", __FUNCTION__, __LINE__); |
| |
| /* wait GSC */ |
| CLOGV("INFO(%s[%d]):wait GSC output pipe(%d)", __FUNCTION__, __LINE__, gscPipe); |
| ret = m_thumbnailCallbackQ->waitAndPopProcessQ(&postgscReprocessingSrcBuffer); |
| CLOGD("INFO(%s[%d]):GSC output done pipe(%d)", __FUNCTION__, __LINE__, gscPipe); |
| if (ret < 0) { |
| CLOGE("ERR(%s)(%d):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| /* TODO: doing exception handling */ |
| goto CLEAN; |
| } |
| |
| m_getBufferManager(gscPipe, &srcbufferMgr, SRC_BUFFER_DIRECTION); |
| m_getBufferManager(gscPipe, &dstbufferMgr, DST_BUFFER_DIRECTION); |
| |
| callbackFrame = m_previewFrameFactory->createNewFrameOnlyOnePipe(gscPipe, framecount); |
| |
| previewFormat = m_exynosCameraParameters->getHwPreviewFormat(); |
| m_exynosCameraParameters->getThumbnailSize(&thumbnailW, &thumbnailH); |
| m_exynosCameraParameters->getPreviewSize(&previewW, &previewH); |
| |
| do { |
| dstbufferIndex = -2; |
| retry++; |
| |
| if (dstbufferMgr->getNumOfAvailableBuffer() > 0) |
| dstbufferMgr->getBuffer(&dstbufferIndex, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL, &postgscReprocessingDstBuffer); |
| if (dstbufferIndex < 0) { |
| usleep(WAITING_TIME); |
| if (retry % 20 == 0) { |
| CLOGW("WRN(%s[%d]):retry Post View Thumbnail getBuffer)", __FUNCTION__, __LINE__); |
| dstbufferMgr->dump(); |
| } |
| } |
| } while (dstbufferIndex < 0 && retry < (TOTAL_WAITING_TIME / WAITING_TIME) && m_flagThreadStop != true && m_stopBurstShot == false); |
| |
| srcRect.x = 0; |
| srcRect.y = 0; |
| srcRect.w = previewW; |
| srcRect.h = previewH; |
| srcRect.fullW = previewW; |
| srcRect.fullH = previewH; |
| srcRect.colorFormat = HAL_PIXEL_FORMAT_2_V4L2_PIX(HAL_PIXEL_FORMAT_YCrCb_420_SP); |
| |
| dstRect.x = 0; |
| dstRect.y = 0; |
| dstRect.w = thumbnailW; |
| dstRect.h = thumbnailH; |
| dstRect.fullW = thumbnailW; |
| dstRect.fullH = thumbnailH; |
| dstRect.colorFormat = HAL_PIXEL_FORMAT_2_V4L2_PIX(HAL_PIXEL_FORMAT_RGBA_8888); |
| |
| CLOGD("DEBUG(%s[%d]):srcBuf(%d) dstBuf(%d) (%d, %d, %d, %d) format(%d) actual(%x) -> (%d, %d, %d, %d) format(%d) actual(%x)", |
| __FUNCTION__, __LINE__, postgscReprocessingSrcBuffer.index, postgscReprocessingDstBuffer.index, |
| srcRect.x, srcRect.y, srcRect.w, srcRect.h, srcRect.colorFormat, V4L2_PIX_2_HAL_PIXEL_FORMAT(srcRect.colorFormat), |
| dstRect.x, dstRect.y, dstRect.w, dstRect.h, dstRect.colorFormat, V4L2_PIX_2_HAL_PIXEL_FORMAT(previewFormat)); |
| |
| ret = callbackFrame->setSrcRect(gscPipe, srcRect); |
| ret = callbackFrame->setDstRect(gscPipe, dstRect); |
| |
| ret = m_setupEntity(gscPipe, callbackFrame, &postgscReprocessingSrcBuffer, &postgscReprocessingDstBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, gscPipe, ret); |
| goto CLEAN; |
| } |
| |
| #ifdef SAMSUNG_LLS_DEBLUR |
| if (m_exynosCameraParameters->getLDCaptureMode()) { |
| m_pictureFrameFactory->setFlagFlipIgnore(gscPipe, true); |
| } |
| #endif |
| |
| m_pictureFrameFactory->setOutputFrameQToPipe(m_ThumbnailPostCallbackQ, gscPipe); |
| m_pictureFrameFactory->pushFrameToPipe(&callbackFrame, gscPipe); |
| |
| /* wait GSC done */ |
| CLOGV("INFO(%s[%d]):wait GSC output", __FUNCTION__, __LINE__); |
| waitCount = 0; |
| |
| do { |
| ret = m_ThumbnailPostCallbackQ->waitAndPopProcessQ(&callbackFrame); |
| waitCount++; |
| } while (ret == TIMED_OUT && waitCount < 100 && m_flagThreadStop != true); |
| |
| if (ret < 0) { |
| CLOGW("WARN(%s[%d]):GSC wait and pop return, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| |
| if (callbackFrame == NULL) { |
| CLOGE("ERR(%s[%d]):frame is NULL", __FUNCTION__, __LINE__); |
| goto CLEAN; |
| } |
| |
| |
| ret = callbackFrame->getDstBuffer(gscPipe, &postgscReprocessingDstBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, gscPipe, ret); |
| goto CLEAN; |
| } |
| |
| #if 0 /* dump code */ |
| char filePath[70]; |
| memset(filePath, 0, sizeof(filePath)); |
| snprintf(filePath, sizeof(filePath), "/data/media/0/RawCapture%d_%d.rgb", |
| m_exynosCameraParameters->getCameraId(), newFrame->getFrameCount()); |
| |
| ret = dumpToFile((char *)filePath, |
| postgscReprocessingDstBuffer.addr[0], |
| FRAME_SIZE(HAL_PIXEL_FORMAT_RGBA_8888, thumbnailW, thumbnailH)); |
| #endif |
| |
| m_postviewCallbackQ->pushProcessQ(&postgscReprocessingDstBuffer); |
| |
| CLOGD("DEBUG(%s[%d]):--OUT--", __FUNCTION__, __LINE__); |
| |
| CLEAN: |
| |
| m_pictureFrameFactory->setFlagFlipIgnore(gscPipe, false); |
| |
| if (postgscReprocessingDstBuffer.index != -2 && ret < 0) |
| m_putBuffers(dstbufferMgr, postgscReprocessingDstBuffer.index); |
| |
| if (postgscReprocessingSrcBuffer.index != -2) |
| m_putBuffers(srcbufferMgr, postgscReprocessingSrcBuffer.index); |
| |
| if (callbackFrame != NULL) { |
| callbackFrame->printEntity(); |
| CLOGD("DEBUG(%s[%d]): Reprocessing frame delete(%d)", __FUNCTION__, __LINE__, callbackFrame->getFrameCount()); |
| callbackFrame->decRef(); |
| m_frameMgr->deleteFrame(callbackFrame); |
| callbackFrame = NULL; |
| } |
| |
| return loop; |
| } |
| |
| bool ExynosCamera::m_postPictureGscThreadFunc(void) |
| { |
| CLOGI("INFO(%s[%d]):", __FUNCTION__, __LINE__); |
| int loop = false; |
| ExynosCameraFrame *newFrame = NULL; |
| int ret = 0; |
| int pipeId_postPictureGsc = PIPE_GSC_VIDEO; |
| ExynosCameraBuffer postgscReprocessingBuffer; |
| ExynosCameraBufferManager *bufferMgr = NULL; |
| camera_memory_t *postviewCallbackHeap = NULL; |
| #ifdef SAMSUNG_BD |
| int previewW = 0, previewH = 0; |
| ExynosCameraDurationTimer m_timer; |
| long long durationTime = 0; |
| bool isThumbnailCallbackOn = false; |
| #if 0 |
| char filePath[70] = "/data/media/0/BD_input.yuv"; |
| #endif |
| #endif |
| |
| postgscReprocessingBuffer.index = -2; |
| |
| if(m_exynosCameraParameters->isReprocessing() == true) { |
| pipeId_postPictureGsc = PIPE_GSC_REPROCESSING2; |
| } else { |
| pipeId_postPictureGsc = PIPE_GSC_VIDEO; |
| } |
| |
| m_getBufferManager(pipeId_postPictureGsc, &bufferMgr, DST_BUFFER_DIRECTION); |
| |
| /* wait GSC */ |
| CLOGI("INFO(%s[%d]):wait GSC output pipe(%d)", __FUNCTION__, __LINE__, pipeId_postPictureGsc); |
| ret = dstPostPictureGscQ->waitAndPopProcessQ(&newFrame); |
| CLOGI("INFO(%s[%d]):GSC output done pipe(%d)", __FUNCTION__, __LINE__, pipeId_postPictureGsc); |
| if (ret < 0) { |
| CLOGE("ERR(%s)(%d):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| /* TODO: doing exception handling */ |
| goto CLEAN; |
| } |
| |
| if (newFrame == NULL) { |
| CLOGE("ERR(%s):newFrame is NULL", __FUNCTION__); |
| goto CLEAN; |
| } |
| |
| ret = newFrame->setEntityState(pipeId_postPictureGsc, ENTITY_STATE_COMPLETE); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setEntityState(ENTITY_STATE_PROCESSING) fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId_postPictureGsc, ret); |
| return ret; |
| } |
| |
| /* put GCC buffer */ |
| ret = newFrame->getDstBuffer(pipeId_postPictureGsc, &postgscReprocessingBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId_postPictureGsc, ret); |
| goto CLEAN; |
| } |
| |
| if (m_exynosCameraParameters->getIsThumbnailCallbackOn()) { |
| m_ThumbnailCallbackThread->run(); |
| m_thumbnailCallbackQ->pushProcessQ(&postgscReprocessingBuffer); |
| CLOGD("DEBUG(%s[%d]): m_ThumbnailCallbackThread run", __FUNCTION__, __LINE__); |
| #ifdef SAMSUNG_BD |
| isThumbnailCallbackOn = true; |
| #endif |
| } |
| #ifdef SAMSUNG_MAGICSHOT |
| else if(m_exynosCameraParameters->getShotMode() == SHOT_MODE_MAGIC) { |
| if(m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_POSTVIEW_FRAME)) { |
| if( m_burstCaptureCallbackCount < m_magicshotMaxCount ) { |
| postviewCallbackHeap = m_getMemoryCb(postgscReprocessingBuffer.fd[0], |
| postgscReprocessingBuffer.size[0], 1, m_callbackCookie); |
| if (!postviewCallbackHeap || postviewCallbackHeap->data == MAP_FAILED) { |
| CLOGE("ERR(%s[%d]):m_getMemoryCb(%d) fail", __FUNCTION__, __LINE__, postgscReprocessingBuffer.size[0]); |
| goto CLEAN; |
| } |
| setBit(&m_callbackState, CALLBACK_STATE_POSTVIEW_FRAME, true); |
| m_dataCb(CAMERA_MSG_POSTVIEW_FRAME, postviewCallbackHeap, 0, NULL, m_callbackCookie); |
| clearBit(&m_callbackState, CALLBACK_STATE_POSTVIEW_FRAME, true); |
| postviewCallbackHeap->release(postviewCallbackHeap); |
| CLOGD("magic shot POSTVIEW callback end(%s)(%d), pipe(%d), index(%d), count(%d), max(%d)", |
| __FUNCTION__, __LINE__, pipeId_postPictureGsc, postgscReprocessingBuffer.index, |
| m_burstCaptureCallbackCount,m_magicshotMaxCount); |
| } |
| ret = m_putBuffers(bufferMgr, postgscReprocessingBuffer.index); |
| } |
| return loop; |
| } |
| #endif |
| #ifdef SAMSUNG_DEBLUR |
| else if (m_deblurCaptureCount == 0 |
| && m_exynosCameraParameters->getLDCaptureMode() == MULTI_SHOT_MODE_DEBLUR) { |
| m_detectDeblurCaptureThread->run(); |
| m_detectDeblurCaptureQ->pushProcessQ(&postgscReprocessingBuffer); |
| CLOGD("DEBUG(%s[%d]): m_detectDeblurCaptureThread run", __FUNCTION__, __LINE__); |
| return loop; |
| } |
| #endif |
| |
| #ifdef SAMSUNG_BD |
| if(m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_BURST) { |
| m_timer.start(); |
| |
| UniPluginBufferData_t pluginData; |
| m_exynosCameraParameters->getPreviewSize(&previewW, &previewH); |
| memset(&pluginData, 0, sizeof(UniPluginBufferData_t)); |
| pluginData.InWidth = previewW; |
| pluginData.InHeight = previewH; |
| pluginData.InFormat = UNI_PLUGIN_FORMAT_NV21; |
| pluginData.InBuffY = postgscReprocessingBuffer.addr[0]; |
| pluginData.InBuffU = postgscReprocessingBuffer.addr[1]; |
| #if 0 |
| dumpToFile((char *)filePath, |
| postgscReprocessingSrcBuffer.addr[0], |
| (previewW * previewH * 3) / 2); |
| #endif |
| if(m_BDpluginHandle != NULL) { |
| ret = uni_plugin_set(m_BDpluginHandle, |
| BLUR_DETECTION_PLUGIN_NAME, UNI_PLUGIN_INDEX_BUFFER_INFO, &pluginData); |
| if(ret < 0) { |
| CLOGE("[BD](%s[%d]): Plugin set(UNI_PLUGIN_INDEX_BUFFER_INFO) failed!!", __FUNCTION__, __LINE__); |
| } |
| ret = uni_plugin_process(m_BDpluginHandle); |
| if(ret < 0) { |
| CLOGE("[BD](%s[%d]): Plugin process failed!!", __FUNCTION__, __LINE__); |
| } |
| ret = uni_plugin_get(m_BDpluginHandle, |
| BLUR_DETECTION_PLUGIN_NAME, UNI_PLUGIN_INDEX_DEBUG_INFO, &m_BDbuffer[m_BDbufferIndex]); |
| if(ret < 0) { |
| CLOGE("[BD](%s[%d]): Plugin get failed!!", __FUNCTION__, __LINE__); |
| } |
| CLOGD("[BD](%s[%d]): Push the buffer(Qsize:%d, Index: %d)", |
| __FUNCTION__, __LINE__, m_BDbufferQ->getSizeOfProcessQ(), m_BDbufferIndex); |
| if(m_BDbufferQ->getSizeOfProcessQ() == MAX_BD_BUFF_NUM) |
| CLOGE("[BD](%s[%d]): All buffers are queued!! Skip the buffer!!", __FUNCTION__, __LINE__); |
| else |
| m_BDbufferQ->pushProcessQ(&m_BDbuffer[m_BDbufferIndex]); |
| |
| if(++m_BDbufferIndex == MAX_BD_BUFF_NUM) |
| m_BDbufferIndex = 0; |
| } |
| |
| m_timer.stop(); |
| durationTime = m_timer.durationMsecs(); |
| CLOGD("[BD](%s[%d]):Plugin duration time(%5d msec)", __FUNCTION__, __LINE__, (int)durationTime); |
| } |
| |
| if (isThumbnailCallbackOn == false) { |
| if (postgscReprocessingBuffer.index != -2) |
| m_putBuffers(bufferMgr, postgscReprocessingBuffer.index); |
| } |
| #endif |
| |
| return loop; |
| |
| CLEAN: |
| if (postgscReprocessingBuffer.index != -2) |
| m_putBuffers(bufferMgr, postgscReprocessingBuffer.index); |
| |
| if (newFrame != NULL) { |
| newFrame->printEntity(); |
| CLOGD("DEBUG(%s[%d]): Reprocessing frame delete(%d)", __FUNCTION__, __LINE__, newFrame->getFrameCount()); |
| newFrame->decRef(); |
| m_frameMgr->deleteFrame(newFrame); |
| newFrame = NULL; |
| } |
| |
| /* one shot */ |
| return loop; |
| } |
| |
| #ifdef SAMSUNG_LBP |
| bool ExynosCamera::m_LBPThreadFunc(void) |
| { |
| lbp_buffer_t LBPbuff; |
| int ret; |
| bool loop = true; |
| |
| ExynosCameraDurationTimer m_timer; |
| long long durationTime = 0; |
| int HwPreviewW = 0, HwPreviewH = 0; |
| |
| ret = m_LBPbufferQ->waitAndPopProcessQ(&LBPbuff); |
| |
| if (m_flagThreadStop == true) { |
| CLOGI("INFO(%s[%d]):m_flagThreadStop(%d)", __FUNCTION__, __LINE__, m_flagThreadStop); |
| m_LBPCount = 0; |
| return false; |
| } |
| |
| if(ret == TIMED_OUT || ret < 0) { |
| CLOGE("ERR(%s)(%d):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| m_captureSelector->setBestFrameNum(0); |
| m_LBPCount = 0; |
| return false; |
| } |
| |
| CLOGD("[LBP]: Buffer pushed(%d):%p, %p!!", LBPbuff.buffer.index, LBPbuff.buffer.addr[0], LBPbuff.buffer.addr[1]); |
| m_LBPCount ++; |
| |
| if(m_LBPpluginHandle != NULL) { |
| m_exynosCameraParameters->getHwPreviewSize(&HwPreviewW, &HwPreviewH); |
| UniPluginBufferData_t pluginData; |
| memset(&pluginData, 0, sizeof(UniPluginBufferData_t)); |
| pluginData.InBuffY= LBPbuff.buffer.addr[0]; |
| pluginData.InBuffU = LBPbuff.buffer.addr[1]; |
| pluginData.InWidth = HwPreviewW; |
| pluginData.InHeight = HwPreviewH; |
| |
| m_timer.start(); |
| ret = uni_plugin_set(m_LBPpluginHandle, BESTPHOTO_PLUGIN_NAME, UNI_PLUGIN_INDEX_BUFFER_INFO, &pluginData); |
| if(ret < 0) |
| CLOGE("[LBP](%s[%d]):Bestphoto plugin set failed!!", __FUNCTION__, __LINE__); |
| ret = uni_plugin_process(m_LBPpluginHandle); |
| if(ret < 0) |
| CLOGE("[LBP](%s[%d]):Bestphoto plugin process failed!!", __FUNCTION__, __LINE__); |
| m_timer.stop(); |
| durationTime = m_timer.durationMsecs(); |
| CLOGD("[LBP](%s[%d]):duration time(%5d msec)", __FUNCTION__, __LINE__, (int)durationTime); |
| } |
| |
| if(m_LBPCount == m_exynosCameraParameters->getHoldFrameCount()) { |
| int bestPhotoIndex; |
| ret = uni_plugin_get(m_LBPpluginHandle, BESTPHOTO_PLUGIN_NAME, UNI_PLUGIN_INDEX_BUFFER_INDEX, &bestPhotoIndex); |
| if(ret < 0) |
| CLOGE("[LBP](%s[%d]):Bestphoto plugin get failed!!", __FUNCTION__, __LINE__); |
| |
| CLOGD("[LBP]: Best photo index(%d), frame(%d)", bestPhotoIndex, m_LBPbuffer[bestPhotoIndex].frameNumber); |
| #if 0 |
| /* To check the performance */ |
| bool bRet; |
| char filePath[70]; |
| for(int i = 0; i < m_LBPCount; i++) { |
| memset(filePath, 0, sizeof(filePath)); |
| if(i == bestPhotoIndex) |
| snprintf(filePath, sizeof(filePath), "/data/media/0/DCIM/Bestphoto_%d_Pick.yuv", m_LBPbuffer[i].frameNumber); |
| else |
| snprintf(filePath, sizeof(filePath), "/data/media/0/DCIM/Bestphoto_%d.yuv", m_LBPbuffer[i].frameNumber); |
| |
| bRet = dumpToFileYUV((char *)filePath, |
| m_LBPbuffer[i].buffer.addr[0], m_LBPbuffer[i].buffer.addr[1], |
| HwPreviewW, HwPreviewH); |
| if (bRet != true) |
| CLOGE("couldn't make a YUV file"); |
| } |
| #endif |
| m_captureSelector->setBestFrameNum(m_LBPbuffer[bestPhotoIndex].frameNumber); |
| #ifdef SAMSUNG_JQ |
| if(m_isJpegQtableOn == true) { |
| m_isJpegQtableOn = false; |
| ret = m_processJpegQtable(&m_LBPbuffer[bestPhotoIndex].buffer); |
| if (ret < 0) { |
| CLOGE("[JQ](%s[%d]): m_processJpegQtable() failed!!", __FUNCTION__, __LINE__); |
| } |
| } |
| #endif |
| } |
| |
| if(m_LBPCount == m_exynosCameraParameters->getHoldFrameCount()) { |
| m_LBPCount = 0; |
| loop = false; |
| } |
| else |
| loop = true; |
| |
| return loop; |
| } |
| #endif |
| #ifdef SAMSUNG_JQ |
| int ExynosCamera::m_processJpegQtable(ExynosCameraBuffer* buffer) |
| { |
| int ret = 0; |
| int HwPreviewW = 0, HwPreviewH = 0; |
| UniPluginBufferData_t pluginData; |
| |
| ExynosCameraDurationTimer m_timer; |
| long long durationTime = 0; |
| |
| m_timer.start(); |
| |
| m_exynosCameraParameters->getHwPreviewSize(&HwPreviewW, &HwPreviewH); |
| |
| memset(&pluginData, 0, sizeof(UniPluginBufferData_t)); |
| pluginData.InBuffY = buffer->addr[0]; |
| pluginData.InBuffU = buffer->addr[1]; |
| pluginData.InWidth = HwPreviewW; |
| pluginData.InHeight = HwPreviewH; |
| pluginData.InFormat = UNI_PLUGIN_FORMAT_NV21; |
| |
| if(m_JQpluginHandle != NULL) { |
| ret = uni_plugin_set(m_JQpluginHandle, |
| JPEG_QTABLE_PLUGIN_NAME, UNI_PLUGIN_INDEX_BUFFER_INFO, &pluginData); |
| if(ret < 0) { |
| CLOGE("[JQ](%s[%d]): Plugin set(UNI_PLUGIN_INDEX_BUFFER_INFO) failed!!", __FUNCTION__, __LINE__); |
| } |
| ret = uni_plugin_process(m_JQpluginHandle); |
| if(ret < 0) { |
| CLOGE("[JQ](%s[%d]): Plugin process failed!!", __FUNCTION__, __LINE__); |
| } |
| ret = uni_plugin_get(m_JQpluginHandle, |
| JPEG_QTABLE_PLUGIN_NAME, UNI_PLUGIN_INDEX_JPEG_QTABLE, m_qtable); |
| if(ret < 0) { |
| CLOGE("[JQ](%s[%d]): Plugin get(UNI_PLUGIN_INDEX_JPEG_QTABLE) failed!!", __FUNCTION__, __LINE__); |
| } |
| |
| CLOGD("[JQ](%s[%d]): Qtable Set Done!!", __FUNCTION__, __LINE__); |
| m_exynosCameraParameters->setJpegQtable(m_qtable); |
| m_exynosCameraParameters->setJpegQtableStatus(JPEG_QTABLE_UPDATED); |
| } |
| |
| m_timer.stop(); |
| durationTime = m_timer.durationMsecs(); |
| CLOGD("[JQ](%s[%d]):duration time(%5d msec)", __FUNCTION__, __LINE__, (int)durationTime); |
| |
| return ret; |
| } |
| #endif |
| |
| bool ExynosCamera::m_CheckCameraSavingPath(char *dir, char* srcPath, char *dstPath, int dstSize) |
| { |
| int ret = false; |
| |
| struct dirent **items = NULL; |
| struct stat fstat; |
| int item_count, i; |
| char ChangeDirPath[CAMERA_FILE_PATH_SIZE] = {'\0',}; |
| |
| memset(dstPath, 0, dstSize); |
| |
| // Check access path |
| if (srcPath && dstSize > (int)strlen(srcPath)) { |
| strncpy(dstPath, srcPath, dstSize - 1); |
| } else { |
| CLOGW("WARN(%s[%d]) Parameter srcPath is NULL. Change to Default Path", __FUNCTION__, __LINE__); |
| snprintf(dstPath, dstSize, "%s/DCIM/Camera/", dir); |
| } |
| |
| if (access(dstPath, 0)==0) { |
| CLOGW("WARN(%s[%d]) success access dir = %s", __FUNCTION__, __LINE__, dstPath); |
| return true; |
| } |
| |
| CLOGW("WARN(%s[%d]) can't access dir = %s, root dir = %s", __FUNCTION__, __LINE__, m_burstSavePath, dir); |
| |
| // If directory cant't access, then search "DCIM/Camera" folder in current directory |
| item_count = scandir(dir, &items, NULL, alphasort); |
| for (i = 0 ; i < item_count ; i++) { |
| // Search only dcim directory |
| lstat(items[i]->d_name, &fstat); |
| if ((fstat.st_mode & S_IFDIR) == S_IFDIR) { |
| if (!strcmp(items[i]->d_name, ".") || !strcmp(items[i]->d_name, "..")) |
| continue; |
| if (strcasecmp(items[i]->d_name, "DCIM")==0) { |
| sprintf(ChangeDirPath, "%s/%s", dir, items[i]->d_name); |
| break; |
| } |
| } |
| } |
| |
| if (items != NULL) { |
| for (i = 0; i < item_count; i++) { |
| if (items[i] != NULL) { |
| free(items[i]); |
| } |
| } |
| free(items); |
| items = NULL; |
| } |
| |
| // If "DCIM" directory exists, search "CAMERA" directory |
| if (ChangeDirPath[0] != '\0') { |
| item_count = scandir(ChangeDirPath, &items, NULL, alphasort); |
| for (i = 0; i < item_count; i++) { |
| // Search only camera directory |
| lstat(items[i]->d_name, &fstat); |
| if ((fstat.st_mode & S_IFDIR) == S_IFDIR) { |
| if (!strcmp(items[i]->d_name, ".") || !strcmp(items[i]->d_name, "..")) |
| continue; |
| if (strcasecmp(items[i]->d_name, "CAMERA")==0) { |
| sprintf(dstPath, "%s/%s/", ChangeDirPath, items[i]->d_name); |
| CLOGW("WARN(%s[%d]) change save path = %s", __FUNCTION__, __LINE__, dstPath); |
| ret = true; |
| break; |
| } |
| } |
| } |
| |
| if (items != NULL) { |
| for (i = 0; i < item_count; i++) { |
| if (items[i] != NULL) { |
| free(items[i]); |
| } |
| } |
| free(items); |
| } |
| } |
| |
| return ret; |
| } |
| |
| bool ExynosCamera::m_FileSaveFunc(char *filePath, ExynosCameraBuffer *SaveBuf) |
| { |
| int fd = -1; |
| int nw, cnt = 0; |
| uint32_t written = 0; |
| char *data; |
| |
| fd = open(filePath, O_RDWR | O_CREAT, 0664); |
| if (fd < 0) { |
| CLOGD("DEBUG(%s[%d]):failed to create file [%s]: %s", |
| __FUNCTION__, __LINE__, filePath, strerror(errno)); |
| goto SAVE_ERR; |
| } |
| |
| data = SaveBuf->addr[0]; |
| |
| CLOGD("DEBUG(%s[%d]):(%s)file write start)", __FUNCTION__, __LINE__, filePath); |
| while (written < SaveBuf->size[0]) { |
| nw = ::write(fd, (const char *)(data) + written, SaveBuf->size[0] - written); |
| |
| if (nw < 0) { |
| CLOGD("DEBUG(%s[%d]):failed to write file [%s]: %s", |
| __FUNCTION__, __LINE__, filePath, strerror(errno)); |
| break; |
| } |
| |
| written += nw; |
| cnt++; |
| } |
| CLOGD("DEBUG(%s[%d]):(%s)file write end)", __FUNCTION__, __LINE__, filePath); |
| |
| if (fd > 0) |
| ::close(fd); |
| |
| if (chmod(filePath, 0664) < 0) { |
| CLOGE("failed chmod [%s]", filePath); |
| } |
| if (chown(filePath, AID_MEDIA, AID_MEDIA_RW) < 0) { |
| CLOGE("failed chown [%s] user(%d), group(%d)", filePath, AID_MEDIA, AID_MEDIA_RW); |
| } |
| |
| return true; |
| |
| SAVE_ERR: |
| |
| return false; |
| } |
| |
| bool ExynosCamera::m_pictureThreadFunc(void) |
| { |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| CLOGI("INFO(%s[%d]):", __FUNCTION__, __LINE__); |
| |
| int ret = 0; |
| int loop = false; |
| int bufIndex = -2; |
| int retryCountGSC = 4; |
| |
| ExynosCameraFrame *newFrame = NULL; |
| |
| ExynosCameraBuffer sccReprocessingBuffer; |
| ExynosCameraBufferManager *bufferMgr = NULL; |
| struct camera2_stream *shot_stream = NULL; |
| ExynosRect srcRect, dstRect; |
| int pictureW = 0, pictureH = 0, pictureFormat = 0; |
| int hwPictureW = 0, hwPictureH = 0, hwPictureFormat = 0; |
| int buffer_idx = getShotBufferIdex(); |
| float zoomRatio = m_exynosCameraParameters->getZoomRatio(0) / 1000; |
| |
| sccReprocessingBuffer.index = -2; |
| |
| int pipeId_scc = 0; |
| int pipeId_gsc = 0; |
| bool isSrc = false; |
| |
| if (m_exynosCameraParameters->isReprocessing() == true) { |
| if (m_exynosCameraParameters->isReprocessing3aaIspOTF() == false) |
| pipeId_scc = (isOwnScc(getCameraId()) == true) ? PIPE_SCC_REPROCESSING : PIPE_ISP_REPROCESSING; |
| else |
| pipeId_scc = PIPE_3AA_REPROCESSING; |
| |
| pipeId_gsc = PIPE_GSC_REPROCESSING; |
| isSrc = true; |
| } else { |
| switch (getCameraId()) { |
| case CAMERA_ID_FRONT: |
| if (m_exynosCameraParameters->getDualMode() == true) { |
| pipeId_scc = PIPE_3AA; |
| } else { |
| pipeId_scc = (isOwnScc(getCameraId()) == true) ? PIPE_SCC : PIPE_ISPC; |
| } |
| pipeId_gsc = PIPE_GSC_PICTURE; |
| break; |
| default: |
| CLOGE("ERR(%s[%d]):Current picture mode is not yet supported, CameraId(%d), reprocessing(%d)", |
| __FUNCTION__, __LINE__, getCameraId(), m_exynosCameraParameters->isReprocessing()); |
| break; |
| } |
| } |
| |
| /* wait SCC */ |
| CLOGI("INFO(%s[%d]):wait SCC output", __FUNCTION__, __LINE__); |
| int retry = 0; |
| do { |
| ret = dstSccReprocessingQ->waitAndPopProcessQ(&newFrame); |
| retry++; |
| } while (ret == TIMED_OUT && retry < 40 && |
| (m_takePictureCounter.getCount() > 0 || m_exynosCameraParameters->getSeriesShotCount() == 0)); |
| |
| if (ret < 0) { |
| CLOGW("WARN(%s[%d]):wait and pop fail, ret(%d), retry(%d), takePictuerCount(%d), seriesShotCount(%d)", |
| __FUNCTION__, __LINE__, ret, retry, m_takePictureCounter.getCount(), m_exynosCameraParameters->getSeriesShotCount()); |
| // TODO: doing exception handling |
| goto CLEAN; |
| } |
| |
| if (newFrame == NULL) { |
| CLOGE("ERR(%s[%d]):newFrame is NULL", __FUNCTION__, __LINE__); |
| goto CLEAN; |
| } |
| |
| if (m_postProcessList.empty()) { |
| CLOGE("ERR(%s[%d]): postPictureList is empty", __FUNCTION__, __LINE__); |
| usleep(5000); |
| if(m_postProcessList.empty()) { |
| CLOGE("ERR(%s[%d]):Retry but postPictureList is empty", __FUNCTION__, __LINE__); |
| goto CLEAN; |
| } |
| } |
| |
| /* |
| * When Non-reprocessing scenario does not setEntityState, |
| * because Non-reprocessing scenario share preview and capture frames |
| */ |
| if (m_exynosCameraParameters->isReprocessing() == true) { |
| ret = newFrame->setEntityState(pipeId_scc, ENTITY_STATE_COMPLETE); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setEntityState(ENTITY_STATE_COMPLETE) fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId_scc, ret); |
| return ret; |
| } |
| } |
| |
| CLOGI("INFO(%s[%d]):SCC output done, frame Count(%d)", __FUNCTION__, __LINE__, newFrame->getFrameCount()); |
| |
| /* Shutter Callback */ |
| if (pipeId_scc != PIPE_SCC_REPROCESSING && |
| pipeId_scc != PIPE_ISP_REPROCESSING) { |
| if (m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_SHUTTER)) { |
| CLOGI("INFO(%s[%d]): CAMERA_MSG_SHUTTER callback S", __FUNCTION__, __LINE__); |
| #ifdef BURST_CAPTURE |
| m_notifyCb(CAMERA_MSG_SHUTTER, m_exynosCameraParameters->getSeriesShotDuration(), 0, m_callbackCookie); |
| #else |
| m_notifyCb(CAMERA_MSG_SHUTTER, 0, 0, m_callbackCookie); |
| #endif |
| CLOGI("INFO(%s[%d]): CAMERA_MSG_SHUTTER callback E", __FUNCTION__, __LINE__); |
| } |
| } |
| |
| #ifdef SAMSUNG_DOF |
| if (m_exynosCameraParameters->getShotMode() == SHOT_MODE_OUTFOCUS && |
| m_exynosCameraParameters->getMoveLensTotal() > 0) { |
| CLOGD("[DOF][%s][%d] Lens moved count: %d", |
| "m_pictureThreadFunc", __LINE__, m_lensmoveCount); |
| CLOGD("[DOF][%s][%d] Total count : %d", |
| "m_pictureThreadFunc", __LINE__, m_exynosCameraParameters->getMoveLensTotal()); |
| |
| ExynosCameraActivityAutofocus *autoFocusMgr = m_exynosCameraActivityControl->getAutoFocusMgr(); |
| |
| if(m_lensmoveCount < m_exynosCameraParameters->getMoveLensTotal()) { |
| CLOGD("[DOF][%s][%d] callback done!!: %d", |
| "m_pictureThreadFunc", __LINE__, m_lensmoveCount); |
| autoFocusMgr->setStartLensMove(true); |
| m_lensmoveCount++; |
| m_exynosCameraParameters->setMoveLensCount(m_lensmoveCount); |
| m_exynosCameraParameters->m_setLensPosition(m_lensmoveCount); |
| } |
| else if(m_lensmoveCount == m_exynosCameraParameters->getMoveLensTotal() ){ |
| CLOGD("[DOF][%s][%d] Last callback done!!: %d", |
| "m_pictureThreadFunc", __LINE__, m_lensmoveCount); |
| autoFocusMgr->setStartLensMove(false); |
| |
| m_lensmoveCount = 0; |
| m_exynosCameraParameters->setMoveLensCount(m_lensmoveCount); |
| m_exynosCameraParameters->setMoveLensTotal(m_lensmoveCount); |
| }else { |
| CLOGE("[DOF][%s][%d] unexpected error!!: %d", |
| "m_pictureThreadFunc", __LINE__, m_lensmoveCount); |
| autoFocusMgr->setStartLensMove(false); |
| m_lensmoveCount = 0; |
| m_exynosCameraParameters->setMoveLensCount(m_lensmoveCount); |
| m_exynosCameraParameters->setMoveLensTotal(m_lensmoveCount); |
| } |
| } |
| #endif |
| |
| #ifdef SAMSUNG_DNG |
| struct camera2_dm *dm; |
| struct camera2_udm *udm; |
| |
| dm = new struct camera2_dm; |
| udm = new struct camera2_udm; |
| |
| newFrame->getDynamicMeta(dm); |
| newFrame->getUserDynamicMeta(udm); |
| |
| if(m_exynosCameraParameters->getDNGCaptureModeOn() && |
| (m_dngFrameNumber == dm->request.frameCount || |
| m_exynosCameraParameters->getCaptureExposureTime() > CAMERA_PREVIEW_EXPOSURE_TIME_LIMIT)) { |
| m_exynosCameraParameters->setDngChangedAttribute(dm, udm); |
| m_exynosCameraParameters->setIsUsefulDngInfo(true); |
| } |
| |
| delete dm; |
| delete udm; |
| #endif |
| |
| #ifdef SAMSUNG_DEBLUR |
| if (m_deblurCaptureCount == MAX_DEBLUR_CAPTURE_COUNT - 1) { |
| if (getUseDeblurCaptureOn()) { |
| m_pictureCounter.decCount(); |
| CLOGE("DEBUG(%s[%d]):use De-blur Capture m_pictureCounter(%d)", |
| __FUNCTION__, __LINE__, m_pictureCounter.getCount()); |
| goto CLEAN; |
| } else { |
| m_exynosCameraParameters->setIsThumbnailCallbackOn(true); |
| CLOGE("DEBUG(%s[%d]):Didn't use De-blur Capture m_pictureCounter(%d)", |
| __FUNCTION__, __LINE__, m_pictureCounter.getCount()); |
| } |
| } |
| #endif |
| |
| if (needGSCForCapture(getCameraId()) == true) { |
| /* set GSC buffer */ |
| if (m_exynosCameraParameters->isReprocessing() == true) |
| ret = newFrame->getDstBuffer(pipeId_scc, &sccReprocessingBuffer, m_reprocessingFrameFactory->getNodeType(PIPE_ISPC_REPROCESSING)); |
| else |
| ret = newFrame->getDstBuffer(pipeId_scc, &sccReprocessingBuffer, m_previewFrameFactory->getNodeType(PIPE_ISPC)); |
| |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId_scc, ret); |
| goto CLEAN; |
| } |
| |
| if (m_exynosCameraParameters->getIsThumbnailCallbackOn()) { |
| if (m_ThumbnailCallbackThread->isRunning()) { |
| m_ThumbnailCallbackThread->join(); |
| CLOGD("DEBUG(%s[%d]): m_ThumbnailCallbackThread join", __FUNCTION__, __LINE__); |
| } |
| } |
| |
| if (m_exynosCameraParameters->getIsThumbnailCallbackOn() |
| #ifdef SAMSUNG_MAGICSHOT |
| || m_exynosCameraParameters->getShotMode() == SHOT_MODE_MAGIC |
| #endif |
| #ifdef SAMSUNG_DEBLUR |
| || (m_deblurCaptureCount == 0 && m_exynosCameraParameters->getLDCaptureMode() == MULTI_SHOT_MODE_DEBLUR) |
| #endif |
| #ifdef SAMSUNG_BD |
| || m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_BURST |
| #endif |
| ) { |
| int pipeId_postPictureGsc = PIPE_GSC_REPROCESSING2; |
| ExynosCameraBuffer postgscReprocessingBuffer; |
| int previewW = 0, previewH = 0, previewFormat = 0; |
| ExynosRect srcRect_postPicturegGsc, dstRect_postPicturegGsc; |
| |
| postgscReprocessingBuffer.index = -2; |
| CLOGD("POSTVIEW callback start, m_postPictureGscThread run (%s)(%d) pipe(%d)", |
| __FUNCTION__, __LINE__, pipeId_postPictureGsc); |
| shot_stream = (struct camera2_stream *)(sccReprocessingBuffer.addr[buffer_idx]); |
| |
| if (shot_stream != NULL) { |
| CLOGD("DEBUG(%s[%d]):(%d %d %d %d)", __FUNCTION__, __LINE__, |
| shot_stream->fcount, |
| shot_stream->rcount, |
| shot_stream->findex, |
| shot_stream->fvalid); |
| CLOGD("DEBUG(%s[%d]):(%d %d %d %d)(%d %d %d %d)", __FUNCTION__, __LINE__, |
| shot_stream->input_crop_region[0], |
| shot_stream->input_crop_region[1], |
| shot_stream->input_crop_region[2], |
| shot_stream->input_crop_region[3], |
| shot_stream->output_crop_region[0], |
| shot_stream->output_crop_region[1], |
| shot_stream->output_crop_region[2], |
| shot_stream->output_crop_region[3]); |
| } else { |
| CLOGE("DEBUG(%s[%d]):shot_stream is NULL", __FUNCTION__, __LINE__); |
| } |
| |
| int retry1 = 0; |
| do { |
| ret = -1; |
| retry1++; |
| if (m_postPictureGscBufferMgr->getNumOfAvailableBuffer() > 0) { |
| ret = m_setupEntity(pipeId_postPictureGsc, newFrame, &sccReprocessingBuffer, NULL); |
| } else { |
| /* wait available SCC buffer */ |
| usleep(WAITING_TIME); |
| } |
| if (retry1 % 10 == 0) |
| CLOGW("WRAN(%s[%d]):retry setupEntity for GSC", __FUNCTION__, __LINE__); |
| } while(ret < 0 && retry1 < (TOTAL_WAITING_TIME/WAITING_TIME)); |
| |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail, pipeId(%d), retry(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId_postPictureGsc, retry1, ret); |
| goto CLEAN; |
| } |
| |
| m_exynosCameraParameters->getPreviewSize(&previewW, &previewH); |
| m_exynosCameraParameters->getPictureSize(&pictureW, &pictureH); |
| pictureFormat = m_exynosCameraParameters->getPictureFormat(); |
| previewFormat = m_exynosCameraParameters->getPreviewFormat(); |
| |
| CLOGD("DEBUG(%s):size preview(%d, %d,format:%d)picture(%d, %d,format:%d)", __FUNCTION__, |
| previewW, previewH, previewFormat, pictureW, pictureH, pictureFormat); |
| |
| srcRect_postPicturegGsc.x = shot_stream->input_crop_region[0]; |
| srcRect_postPicturegGsc.y = shot_stream->input_crop_region[1]; |
| srcRect_postPicturegGsc.w = shot_stream->input_crop_region[2]; |
| srcRect_postPicturegGsc.h = shot_stream->input_crop_region[3]; |
| srcRect_postPicturegGsc.fullW = shot_stream->input_crop_region[2]; |
| srcRect_postPicturegGsc.fullH = shot_stream->input_crop_region[3]; |
| srcRect_postPicturegGsc.colorFormat = pictureFormat; |
| dstRect_postPicturegGsc.x = 0; |
| dstRect_postPicturegGsc.y = 0; |
| dstRect_postPicturegGsc.w = previewW; |
| dstRect_postPicturegGsc.h = previewH; |
| dstRect_postPicturegGsc.fullW = previewW; |
| dstRect_postPicturegGsc.fullH = previewH; |
| dstRect_postPicturegGsc.colorFormat = HAL_PIXEL_FORMAT_2_V4L2_PIX(HAL_PIXEL_FORMAT_YCrCb_420_SP); |
| |
| ret = getCropRectAlign(srcRect_postPicturegGsc.w, srcRect_postPicturegGsc.h, |
| previewW, previewH, |
| &srcRect_postPicturegGsc.x, &srcRect_postPicturegGsc.y, |
| &srcRect_postPicturegGsc.w, &srcRect_postPicturegGsc.h, |
| 2, 2, 0, zoomRatio); |
| |
| ret = newFrame->setSrcRect(pipeId_postPictureGsc, &srcRect_postPicturegGsc); |
| ret = newFrame->setDstRect(pipeId_postPictureGsc, &dstRect_postPicturegGsc); |
| |
| CLOGD("DEBUG(%s):size (%d, %d, %d, %d %d %d)", __FUNCTION__, |
| srcRect_postPicturegGsc.x, srcRect_postPicturegGsc.y, srcRect_postPicturegGsc.w, |
| srcRect_postPicturegGsc.h, srcRect_postPicturegGsc.fullW, srcRect_postPicturegGsc.fullH); |
| CLOGD("DEBUG(%s):size (%d, %d, %d, %d %d %d)", __FUNCTION__, |
| dstRect_postPicturegGsc.x, dstRect_postPicturegGsc.y, dstRect_postPicturegGsc.w, |
| dstRect_postPicturegGsc.h, dstRect_postPicturegGsc.fullW, dstRect_postPicturegGsc.fullH); |
| |
| /* push frame to GSC pipe */ |
| m_pictureFrameFactory->setOutputFrameQToPipe(dstPostPictureGscQ, pipeId_postPictureGsc); |
| m_pictureFrameFactory->pushFrameToPipe(&newFrame, pipeId_postPictureGsc); |
| |
| ret = m_postPictureGscThread->run(); |
| |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):couldn't run m_postPictureGscThread, ret(%d)", __FUNCTION__, __LINE__, ret); |
| return INVALID_OPERATION; |
| } |
| } |
| |
| shot_stream = (struct camera2_stream *)(sccReprocessingBuffer.addr[buffer_idx]); |
| if (shot_stream != NULL) { |
| CLOGD("DEBUG(%s[%d]):(%d %d %d %d)", __FUNCTION__, __LINE__, |
| shot_stream->fcount, |
| shot_stream->rcount, |
| shot_stream->findex, |
| shot_stream->fvalid); |
| CLOGD("DEBUG(%s[%d]):(%d %d %d %d)(%d %d %d %d)", __FUNCTION__, __LINE__, |
| shot_stream->input_crop_region[0], |
| shot_stream->input_crop_region[1], |
| shot_stream->input_crop_region[2], |
| shot_stream->input_crop_region[3], |
| shot_stream->output_crop_region[0], |
| shot_stream->output_crop_region[1], |
| shot_stream->output_crop_region[2], |
| shot_stream->output_crop_region[3]); |
| } else { |
| CLOGE("DEBUG(%s[%d]):shot_stream is NULL", __FUNCTION__, __LINE__); |
| goto CLEAN; |
| } |
| |
| int retry = 0; |
| m_getBufferManager(pipeId_gsc, &bufferMgr, DST_BUFFER_DIRECTION); |
| do { |
| ret = -1; |
| retry++; |
| if (bufferMgr->getNumOfAvailableBuffer() > 0) { |
| ret = m_setupEntity(pipeId_gsc, newFrame, &sccReprocessingBuffer, NULL); |
| } else { |
| /* wait available SCC buffer */ |
| usleep(WAITING_TIME); |
| } |
| |
| if (retry % 10 == 0) { |
| CLOGW("WRAN(%s[%d]):retry setupEntity for GSC postPictureQ(%d), saveQ0(%d), saveQ1(%d), saveQ2(%d)", |
| __FUNCTION__, __LINE__, |
| m_postPictureQ->getSizeOfProcessQ(), |
| m_jpegSaveQ[JPEG_SAVE_THREAD0]->getSizeOfProcessQ(), |
| m_jpegSaveQ[JPEG_SAVE_THREAD1]->getSizeOfProcessQ(), |
| m_jpegSaveQ[JPEG_SAVE_THREAD2]->getSizeOfProcessQ()); |
| } |
| } while(ret < 0 && retry < (TOTAL_WAITING_TIME/WAITING_TIME) && m_stopBurstShot == false); |
| |
| if (ret < 0) { |
| if (retry >= (TOTAL_WAITING_TIME/WAITING_TIME)) { |
| CLOGE("ERR(%s[%d]):setupEntity fail, pipeId(%d), retry(%d), ret(%d), m_stopBurstShot(%d)", |
| __FUNCTION__, __LINE__, pipeId_gsc, retry, ret, m_stopBurstShot); |
| /* HACK for debugging P150108-08143 */ |
| bufferMgr->printBufferState(); |
| android_printAssert(NULL, LOG_TAG, "BURST_SHOT_TIME_ASSERT(%s[%d]):\ |
| unexpected error, get GSC buffer failed, assert!!!!", __FUNCTION__, __LINE__); |
| } else { |
| CLOGD("DEBUG(%s[%d]):setupEntity stopped, pipeId(%d), retry(%d), ret(%d), m_stopBurstShot(%d)", |
| __FUNCTION__, __LINE__, pipeId_gsc, retry, ret, m_stopBurstShot); |
| } |
| goto CLEAN; |
| } |
| /* should change size calculation code in pure bayer */ |
| #if 0 |
| if (shot_stream != NULL) { |
| ret = m_calcPictureRect(&srcRect, &dstRect); |
| ret = newFrame->setSrcRect(pipeId_gsc, &srcRect); |
| ret = newFrame->setDstRect(pipeId_gsc, &dstRect); |
| } |
| #else |
| m_exynosCameraParameters->getPictureSize(&pictureW, &pictureH); |
| pictureFormat = m_exynosCameraParameters->getPictureFormat(); |
| #if 1 /* HACK in case of 3AA-OTF-ISP input_cropRegion always 0, use output crop region, check the driver */ |
| srcRect.x = shot_stream->output_crop_region[0]; |
| srcRect.y = shot_stream->output_crop_region[1]; |
| srcRect.w = shot_stream->output_crop_region[2]; |
| srcRect.h = shot_stream->output_crop_region[3]; |
| #endif |
| srcRect.fullW = shot_stream->output_crop_region[2]; |
| srcRect.fullH = shot_stream->output_crop_region[3]; |
| srcRect.colorFormat = pictureFormat; |
| |
| if(m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_LLS |
| || m_exynosCameraParameters->getShotMode() == SHOT_MODE_OUTFOCUS |
| #ifdef SAMSUNG_LLS_DEBLUR |
| || (m_exynosCameraParameters->getLDCaptureMode() |
| #ifdef SAMSUNG_DEBLUR |
| && (m_deblurCaptureCount < m_exynosCameraParameters->getLDCaptureCount() - 1) |
| #endif |
| ) |
| #endif |
| ) { |
| pictureFormat = V4L2_PIX_FMT_NV21; |
| } else { |
| pictureFormat = JPEG_INPUT_COLOR_FMT; |
| } |
| |
| #ifdef SR_CAPTURE |
| if(m_exynosCameraParameters->getSROn() && |
| (m_exynosCameraParameters->getReprocessingBayerMode() == REPROCESSING_BAYER_MODE_DIRTY_ALWAYS_ON || |
| m_exynosCameraParameters->getReprocessingBayerMode() == REPROCESSING_BAYER_MODE_DIRTY_DYNAMIC)) { |
| dstRect.x = 0; |
| dstRect.y = 0; |
| dstRect.w = shot_stream->output_crop_region[2]; |
| dstRect.h = shot_stream->output_crop_region[3]; |
| dstRect.fullW = shot_stream->output_crop_region[2]; |
| dstRect.fullH = shot_stream->output_crop_region[3]; |
| dstRect.colorFormat = pictureFormat; |
| } else |
| #endif |
| { |
| dstRect.x = 0; |
| dstRect.y = 0; |
| dstRect.w = pictureW; |
| dstRect.h = pictureH; |
| dstRect.fullW = pictureW; |
| dstRect.fullH = pictureH; |
| dstRect.colorFormat = pictureFormat; |
| } |
| ret = getCropRectAlign(srcRect.w, srcRect.h, |
| pictureW, pictureH, |
| &srcRect.x, &srcRect.y, |
| &srcRect.w, &srcRect.h, |
| 2, 2, 0, zoomRatio); |
| |
| ret = newFrame->setSrcRect(pipeId_gsc, &srcRect); |
| ret = newFrame->setDstRect(pipeId_gsc, &dstRect); |
| #endif |
| |
| CLOGD("DEBUG(%s):size (%d, %d, %d, %d %d %d)", __FUNCTION__, |
| srcRect.x, srcRect.y, srcRect.w, srcRect.h, srcRect.fullW, srcRect.fullH); |
| CLOGD("DEBUG(%s):size (%d, %d, %d, %d %d %d)", __FUNCTION__, |
| dstRect.x, dstRect.y, dstRect.w, dstRect.h, dstRect.fullW, dstRect.fullH); |
| |
| /* push frame to GSC pipe */ |
| m_pictureFrameFactory->setOutputFrameQToPipe(dstGscReprocessingQ, pipeId_gsc); |
| m_pictureFrameFactory->pushFrameToPipe(&newFrame, pipeId_gsc); |
| |
| /* wait GSC */ |
| newFrame = NULL; |
| CLOGI("INFO(%s[%d]):wait GSC output", __FUNCTION__, __LINE__); |
| while (retryCountGSC > 0) { |
| ret = dstGscReprocessingQ->waitAndPopProcessQ(&newFrame); |
| if (ret == TIMED_OUT) { |
| CLOGW("WRN(%s)(%d):wait and pop timeout, ret(%d)", __FUNCTION__, __LINE__, ret); |
| m_pictureFrameFactory->startThread(pipeId_gsc); |
| } else if (ret < 0) { |
| CLOGE("ERR(%s)(%d):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| /* TODO: doing exception handling */ |
| goto CLEAN; |
| } else if (m_stopBurstShot == true) { |
| CLOGD("DEBUG(%s)(%d):stopburst! ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto CLEAN; |
| } else { |
| break; |
| } |
| retryCountGSC--; |
| } |
| |
| if (newFrame == NULL) { |
| CLOGE("ERR(%s):newFrame is NULL", __FUNCTION__); |
| goto CLEAN; |
| } |
| CLOGI("INFO(%s[%d]):GSC output done", __FUNCTION__, __LINE__); |
| |
| if (m_exynosCameraParameters->getIsThumbnailCallbackOn() |
| #ifdef SAMSUNG_MAGICSHOT |
| || m_exynosCameraParameters->getShotMode() == SHOT_MODE_MAGIC |
| #endif |
| #ifdef SAMSUNG_DEBLUR |
| || (m_deblurCaptureCount == 0 && m_exynosCameraParameters->getLDCaptureMode() == MULTI_SHOT_MODE_DEBLUR) |
| #endif |
| #ifdef SAMSUNG_BD |
| || m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_BURST |
| #endif |
| ) { |
| m_postPictureGscThread->join(); |
| } |
| |
| #ifdef SR_CAPTURE |
| if(m_exynosCameraParameters->getSROn()) { |
| if (m_exynosCameraParameters->getReprocessingBayerMode() == REPROCESSING_BAYER_MODE_DIRTY_ALWAYS_ON || |
| m_exynosCameraParameters->getReprocessingBayerMode() == REPROCESSING_BAYER_MODE_DIRTY_DYNAMIC) { |
| m_sr_cropped_width = shot_stream->output_crop_region[2]; |
| m_sr_cropped_height = shot_stream->output_crop_region[3]; |
| } else { |
| m_sr_cropped_width = pictureW; |
| m_sr_cropped_height = pictureH; |
| } |
| CLOGD("DEBUG(%s):size (%d, %d)", __FUNCTION__, m_sr_cropped_width, m_sr_cropped_height); |
| } |
| #endif |
| |
| /* put SCC buffer */ |
| if (m_exynosCameraParameters->isReprocessing() == true) |
| ret = newFrame->getDstBuffer(pipeId_scc, &sccReprocessingBuffer, m_reprocessingFrameFactory->getNodeType(PIPE_ISPC_REPROCESSING)); |
| else |
| ret = newFrame->getDstBuffer(pipeId_scc, &sccReprocessingBuffer, m_previewFrameFactory->getNodeType(PIPE_ISPC)); |
| |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId_scc, ret); |
| goto CLEAN; |
| } |
| |
| m_getBufferManager(pipeId_scc, &bufferMgr, DST_BUFFER_DIRECTION); |
| ret = m_putBuffers(bufferMgr, sccReprocessingBuffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s)(%d):m_putBuffers fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| /* TODO: doing exception handling */ |
| goto CLEAN; |
| } |
| } |
| |
| #ifdef SAMSUNG_DEBLUR |
| if(m_exynosCameraParameters->getLDCaptureMode() == MULTI_SHOT_MODE_DEBLUR) { |
| m_deblurCaptureCount++; |
| CLOGD("DEBUG(%s[%d]): m_deblurCaptureCoun(%d)", __FUNCTION__, __LINE__, m_deblurCaptureCount); |
| } |
| |
| if (m_exynosCameraParameters->getLDCaptureMode() == MULTI_SHOT_MODE_DEBLUR |
| && m_deblurCaptureCount < m_exynosCameraParameters->getLDCaptureCount()) { |
| m_deblurCaptureQ->pushProcessQ(&newFrame); |
| } else |
| #endif |
| { |
| #ifdef SAMSUNG_LLS_DEBLUR |
| if (m_exynosCameraParameters->getLDCaptureMode() > 0 |
| && m_exynosCameraParameters->getLDCaptureMode() != MULTI_SHOT_MODE_DEBLUR) { |
| m_LDCaptureQ->pushProcessQ(&newFrame); |
| } else |
| #endif |
| { |
| /* push postProcess */ |
| m_postPictureQ->pushProcessQ(&newFrame); |
| } |
| } |
| m_pictureCounter.decCount(); |
| |
| CLOGI("INFO(%s[%d]):picture thread complete, remaining count(%d)", __FUNCTION__, __LINE__, m_pictureCounter.getCount()); |
| |
| if (m_pictureCounter.getCount() > 0) { |
| loop = true; |
| } else { |
| if (m_exynosCameraParameters->isReprocessing() == true) |
| CLOGD("DEBUG(%s[%d]): ", __FUNCTION__, __LINE__); |
| else { |
| if (m_exynosCameraParameters->getUseDynamicScc() == true) { |
| CLOGD("DEBUG(%s[%d]): Use dynamic bayer", __FUNCTION__, __LINE__); |
| |
| if (isOwnScc(getCameraId()) == true) |
| m_previewFrameFactory->setRequestSCC(false); |
| else |
| m_previewFrameFactory->setRequestISPC(false); |
| } |
| |
| m_sccCaptureSelector->clearList(pipeId_scc, isSrc, m_pictureFrameFactory->getNodeType(PIPE_ISPC)); |
| } |
| |
| dstSccReprocessingQ->release(); |
| } |
| |
| /* one shot */ |
| return loop; |
| |
| CLEAN: |
| if (sccReprocessingBuffer.index != -2) { |
| CLOGD("DEBUG(%s[%d]): putBuffer sccReprocessingBuffer(index:%d) in error state", |
| __FUNCTION__, __LINE__, sccReprocessingBuffer.index); |
| m_getBufferManager(pipeId_scc, &bufferMgr, DST_BUFFER_DIRECTION); |
| m_putBuffers(bufferMgr, sccReprocessingBuffer.index); |
| } |
| |
| #ifdef SAMSUNG_DEBLUR |
| if(!getUseDeblurCaptureOn()) { |
| CLOGI("INFO(%s[%d]):take picture fail, remaining count(%d)", __FUNCTION__, __LINE__, m_pictureCounter.getCount()); |
| } |
| #endif |
| |
| if (m_pictureCounter.getCount() > 0) |
| loop = true; |
| |
| /* one shot */ |
| return loop; |
| } |
| |
| camera_memory_t *ExynosCamera::m_getJpegCallbackHeap(ExynosCameraBuffer jpegBuf, int seriesShotNumber) |
| { |
| CLOGI("INFO(%s[%d]):", __FUNCTION__, __LINE__); |
| |
| camera_memory_t *jpegCallbackHeap = NULL; |
| |
| #ifdef BURST_CAPTURE |
| if (1 < m_exynosCameraParameters->getSeriesShotCount()) { |
| int seriesShotSaveLocation = m_exynosCameraParameters->getSeriesShotSaveLocation(); |
| |
| if (seriesShotNumber < 0 || seriesShotNumber > m_exynosCameraParameters->getSeriesShotCount()) { |
| CLOGE("ERR(%s[%d]): Invalid shot number (%d)", __FUNCTION__, __LINE__, seriesShotNumber); |
| goto done; |
| } |
| |
| if (seriesShotSaveLocation == BURST_SAVE_CALLBACK) { |
| CLOGD("DEBUG(%s[%d]):burst callback : size (%d), count(%d)", __FUNCTION__, __LINE__, jpegBuf.size[0], seriesShotNumber); |
| |
| jpegCallbackHeap = m_getMemoryCb(jpegBuf.fd[0], jpegBuf.size[0], 1, m_callbackCookie); |
| if (!jpegCallbackHeap || jpegCallbackHeap->data == MAP_FAILED) { |
| CLOGE("ERR(%s[%d]):m_getMemoryCb(%d) fail", __FUNCTION__, __LINE__, jpegBuf.size[0]); |
| goto done; |
| } |
| if (jpegBuf.fd[0] < 0) |
| memcpy(jpegCallbackHeap->data, jpegBuf.addr[0], jpegBuf.size[0]); |
| } else { |
| char filePath[CAMERA_FILE_PATH_SIZE]; |
| int nw, cnt = 0; |
| uint32_t written = 0; |
| camera_memory_t *tempJpegCallbackHeap = NULL; |
| |
| memset(filePath, 0, sizeof(filePath)); |
| |
| #if defined(SAMSUNG_INF_BURST) |
| snprintf(filePath, sizeof(filePath), "%s%s_%03d.jpg", |
| m_burstSavePath, m_burstTime, seriesShotNumber); |
| #else |
| snprintf(filePath, sizeof(filePath), "%sBurst%02d.jpg", m_burstSavePath, seriesShotNumber); |
| #endif |
| CLOGD("DEBUG(%s[%d]):burst callback : size (%d), filePath(%s)", __FUNCTION__, __LINE__, jpegBuf.size[0], filePath); |
| |
| jpegCallbackHeap = m_getMemoryCb(-1, sizeof(filePath), 1, m_callbackCookie); |
| if (!jpegCallbackHeap || jpegCallbackHeap->data == MAP_FAILED) { |
| CLOGE("ERR(%s[%d]):m_getMemoryCb(%s) fail", __FUNCTION__, __LINE__, filePath); |
| goto done; |
| } |
| |
| memcpy(jpegCallbackHeap->data, filePath, sizeof(filePath)); |
| } |
| } else |
| #endif |
| { |
| CLOGD("DEBUG(%s[%d]):general callback : size (%d)", __FUNCTION__, __LINE__, jpegBuf.size[0]); |
| |
| jpegCallbackHeap = m_getMemoryCb(jpegBuf.fd[0], jpegBuf.size[0], 1, m_callbackCookie); |
| if (!jpegCallbackHeap || jpegCallbackHeap->data == MAP_FAILED) { |
| CLOGE("ERR(%s[%d]):m_getMemoryCb(%d) fail", __FUNCTION__, __LINE__, jpegBuf.size[0]); |
| goto done; |
| } |
| |
| if (jpegBuf.fd[0] < 0) |
| memcpy(jpegCallbackHeap->data, jpegBuf.addr[0], jpegBuf.size[0]); |
| } |
| |
| done: |
| if (jpegCallbackHeap == NULL || |
| jpegCallbackHeap->data == MAP_FAILED) { |
| |
| if (jpegCallbackHeap) { |
| jpegCallbackHeap->release(jpegCallbackHeap); |
| jpegCallbackHeap = NULL; |
| } |
| |
| m_notifyCb(CAMERA_MSG_ERROR, -1, 0, m_callbackCookie); |
| } |
| |
| CLOGD("INFO(%s[%d]):making callback buffer done", __FUNCTION__, __LINE__); |
| |
| return jpegCallbackHeap; |
| } |
| |
| bool ExynosCamera::m_postPictureThreadFunc(void) |
| { |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| CLOGI("INFO(%s[%d]):", __FUNCTION__, __LINE__); |
| |
| int ret = 0; |
| int loop = false; |
| int bufIndex = -2; |
| int buffer_idx = getShotBufferIdex(); |
| int retryCountJPEG = 4; |
| |
| ExynosCameraFrame *newFrame = NULL; |
| |
| ExynosCameraBuffer gscReprocessingBuffer; |
| ExynosCameraBuffer jpegReprocessingBuffer; |
| |
| gscReprocessingBuffer.index = -2; |
| jpegReprocessingBuffer.index = -2; |
| |
| int pipeId_gsc = 0; |
| int pipeId_jpeg = 0; |
| |
| int currentSeriesShotMode = 0; |
| |
| if (m_exynosCameraParameters->isReprocessing() == true) { |
| if (needGSCForCapture(getCameraId()) == true) { |
| pipeId_gsc = PIPE_GSC_REPROCESSING; |
| } else { |
| pipeId_gsc = (isOwnScc(getCameraId()) == true) ? PIPE_SCC_REPROCESSING : PIPE_ISP_REPROCESSING; |
| } |
| pipeId_jpeg = PIPE_JPEG_REPROCESSING; |
| } else { |
| if (needGSCForCapture(getCameraId()) == true) { |
| pipeId_gsc = PIPE_GSC_PICTURE; |
| } else { |
| if (isOwnScc(getCameraId()) == true) { |
| pipeId_gsc = PIPE_SCC; |
| } else { |
| pipeId_gsc = PIPE_ISPC; |
| } |
| } |
| |
| pipeId_jpeg = PIPE_JPEG; |
| } |
| |
| ExynosCameraBufferManager *bufferMgr = NULL; |
| ret = m_getBufferManager(pipeId_gsc, &bufferMgr, DST_BUFFER_DIRECTION); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getBufferManager(SRC) fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId_gsc, ret); |
| return ret; |
| } |
| |
| CLOGI("INFO(%s[%d]):wait postPictureQ output", __FUNCTION__, __LINE__); |
| ret = m_postPictureQ->waitAndPopProcessQ(&newFrame); |
| if (ret < 0) { |
| CLOGW("WARN(%s[%d]):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| /* TODO: doing exception handling */ |
| goto CLEAN; |
| } |
| if (newFrame == NULL) { |
| CLOGE("ERR(%s[%d]):newFrame is NULL", __FUNCTION__, __LINE__); |
| goto CLEAN; |
| } |
| |
| if (m_jpegCounter.getCount() <= 0) { |
| CLOGD("DEBUG(%s[%d]): Picture canceled", __FUNCTION__, __LINE__); |
| goto CLEAN; |
| } |
| |
| CLOGI("INFO(%s[%d]):postPictureQ output done", __FUNCTION__, __LINE__); |
| |
| #ifdef SAMSUNG_TN_FEATURE |
| /* Save the iso of capture frame to camera parameters for providing App/framework iso info. */ |
| struct camera2_udm *udm; |
| udm = new struct camera2_udm; |
| memset(udm, 0x00, sizeof(struct camera2_udm)); |
| |
| newFrame->getUserDynamicMeta(udm); |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| if (m_exynosCameraParameters->getSeriesShotMode() != SERIES_SHOT_MODE_ONE_SECOND_BURST) |
| #endif |
| { |
| m_exynosCameraParameters->setParamIso(udm); |
| } |
| |
| #ifdef LLS_REPROCESSING |
| if(m_exynosCameraParameters->getSamsungCamera() && m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_LLS) { |
| if (m_exynosCameraParameters->msgTypeEnabled(MULTI_FRAME_SHOT_BV_INFO)) { |
| CLOGD("DEBUG(%s[%d]): MULTI_FRAME_SHOT_BV_INFO BV value %u", __FUNCTION__, __LINE__, udm->awb.vendorSpecific[11]); |
| m_notifyCb(MULTI_FRAME_SHOT_BV_INFO, udm->awb.vendorSpecific[11], 0, m_callbackCookie); |
| } |
| } |
| #endif /* LLS_REPROCESSING */ |
| |
| if (udm != NULL) { |
| delete udm; |
| udm = NULL; |
| } |
| #endif |
| |
| /* put picture callback buffer */ |
| /* get gsc dst buffers */ |
| ret = newFrame->getDstBuffer(pipeId_gsc, &gscReprocessingBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId_gsc, ret); |
| goto CLEAN; |
| } |
| |
| /* callback */ |
| if (m_hdrEnabled == false && m_exynosCameraParameters->getSeriesShotCount() <= 0 |
| #ifdef SAMSUNG_DNG |
| && !m_exynosCameraParameters->getDNGCaptureModeOn() |
| #endif |
| ) { |
| if (m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_RAW_IMAGE)) { |
| CLOGD("DEBUG(%s[%d]): RAW callback", __FUNCTION__, __LINE__); |
| camera_memory_t *rawCallbackHeap = NULL; |
| rawCallbackHeap = m_getMemoryCb(gscReprocessingBuffer.fd[0], gscReprocessingBuffer.size[0], 1, m_callbackCookie); |
| if (!rawCallbackHeap || rawCallbackHeap->data == MAP_FAILED) { |
| CLOGE("ERR(%s[%d]):m_getMemoryCb(%d) fail", __FUNCTION__, __LINE__, gscReprocessingBuffer.size[0]); |
| goto CLEAN; |
| } |
| |
| setBit(&m_callbackState, CALLBACK_STATE_RAW_IMAGE, true); |
| m_dataCb(CAMERA_MSG_RAW_IMAGE, rawCallbackHeap, 0, NULL, m_callbackCookie); |
| clearBit(&m_callbackState, CALLBACK_STATE_RAW_IMAGE, true); |
| rawCallbackHeap->release(rawCallbackHeap); |
| } |
| |
| if (m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_RAW_IMAGE_NOTIFY)) { |
| CLOGD("DEBUG(%s[%d]): RAW_IMAGE_NOTIFY callback", __FUNCTION__, __LINE__); |
| |
| m_notifyCb(CAMERA_MSG_RAW_IMAGE_NOTIFY, 0, 0, m_callbackCookie); |
| } |
| |
| if ((m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_POSTVIEW_FRAME)) |
| && !m_exynosCameraParameters->getIsThumbnailCallbackOn() |
| #ifdef SAMSUNG_MAGICSHOT |
| && (m_exynosCameraParameters->getShotMode() != SHOT_MODE_MAGIC) |
| #endif |
| ) { |
| CLOGD("DEBUG(%s[%d]): POSTVIEW callback", __FUNCTION__, __LINE__); |
| |
| camera_memory_t *postviewCallbackHeap = NULL; |
| postviewCallbackHeap = m_getMemoryCb(gscReprocessingBuffer.fd[0], gscReprocessingBuffer.size[0], 1, m_callbackCookie); |
| if (!postviewCallbackHeap || postviewCallbackHeap->data == MAP_FAILED) { |
| CLOGE("ERR(%s[%d]):m_getMemoryCb(%d) fail", __FUNCTION__, __LINE__, gscReprocessingBuffer.size[0]); |
| goto CLEAN; |
| } |
| |
| setBit(&m_callbackState, CALLBACK_STATE_POSTVIEW_FRAME, true); |
| m_dataCb(CAMERA_MSG_POSTVIEW_FRAME, postviewCallbackHeap, 0, NULL, m_callbackCookie); |
| clearBit(&m_callbackState, CALLBACK_STATE_POSTVIEW_FRAME, true); |
| postviewCallbackHeap->release(postviewCallbackHeap); |
| } |
| } |
| |
| #if 0 // SAMSUNG_MAGICSHOT |
| if ((m_exynosCameraParameters->getShotMode() == SHOT_MODE_MAGIC) && |
| (m_exynosCameraParameters->isReprocessing() == true)) { |
| CLOGD("magic shot rear postview callback star(%s)(%d)", __FUNCTION__, __LINE__); |
| int pipeId_postPictureGsc = 0; |
| ExynosCameraBuffer postgscReprocessingBuffer; |
| ExynosCameraBufferManager *bufferMgr1 = NULL; |
| struct camera2_stream *shot_stream = NULL; |
| ExynosRect srcRect, dstRect; |
| int previewW = 0, previewH = 0, previewFormat = 0; |
| int pictureW = 0, pictureH = 0, pictureFormat = 0; |
| float zoomRatio = m_exynosCameraParameters->getZoomRatio(0) / 1000; |
| |
| postgscReprocessingBuffer.index = -2; |
| pipeId_postPictureGsc = PIPE_GSC_REPROCESSING; |
| |
| shot_stream = (struct camera2_stream *)(gscReprocessingBuffer.addr[buffer_idx]); |
| if (shot_stream == NULL) { |
| CLOGE("ERR(%s[%d]):shot_stream is NULL. buffer(%d)", |
| __FUNCTION__, __LINE__, gscReprocessingBuffer.index); |
| goto CLEAN; |
| } |
| |
| int retry = 0; |
| ret = m_getBufferManager(pipeId_postPictureGsc, &bufferMgr1, DST_BUFFER_DIRECTION); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getBufferManager(GSC) fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId_postPictureGsc, ret); |
| return ret; |
| } |
| |
| do { |
| ret = -1; |
| retry++; |
| if (bufferMgr1->getNumOfAvailableBuffer() > 0) { |
| ret = m_setupEntity(pipeId_postPictureGsc, newFrame, &gscReprocessingBuffer, NULL); |
| } else { |
| /* wait available SCC buffer */ |
| usleep(WAITING_TIME); |
| } |
| |
| if (retry % 10 == 0) |
| CLOGW("WRAN(%s[%d]):retry setupEntity for GSC", __FUNCTION__, __LINE__); |
| } while(ret < 0 && retry < (TOTAL_WAITING_TIME/WAITING_TIME)); |
| |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail, pipeId(%d), retry(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId_postPictureGsc, retry, ret); |
| goto CLEAN; |
| } |
| |
| m_exynosCameraParameters->getPreviewSize(&previewW, &previewH); |
| m_exynosCameraParameters->getPictureSize(&pictureW, &pictureH); |
| pictureFormat = m_exynosCameraParameters->getPictureFormat(); |
| previewFormat = m_exynosCameraParameters->getPreviewFormat(); |
| |
| CLOGD("DEBUG(%s):size preview(%d, %d,format:%d)picture(%d, %d,format:%d)", __FUNCTION__, |
| previewW, previewH,previewFormat,pictureW, pictureH,pictureFormat); |
| |
| srcRect.x = shot_stream->output_crop_region[0]; |
| srcRect.y = shot_stream->output_crop_region[1]; |
| srcRect.w = shot_stream->output_crop_region[2]; |
| srcRect.h = shot_stream->output_crop_region[3]; |
| srcRect.fullW = shot_stream->output_crop_region[2]; |
| srcRect.fullH = shot_stream->output_crop_region[3]; |
| srcRect.colorFormat = SCC_OUTPUT_COLOR_FMT; |
| // srcRect.colorFormat = pictureFormat; |
| dstRect.x = 0; |
| dstRect.y = 0; |
| dstRect.w = previewW; |
| dstRect.h = previewH; |
| dstRect.fullW = previewW; |
| dstRect.fullH = previewH; |
| dstRect.colorFormat = previewFormat; |
| |
| ret = getCropRectAlign(srcRect.w, srcRect.h, |
| previewW, previewH, |
| &srcRect.x, &srcRect.y, |
| &srcRect.w, &srcRect.h, |
| 2, 2, 0, zoomRatio); |
| |
| ret = newFrame->setSrcRect(pipeId_postPictureGsc, &srcRect); |
| ret = newFrame->setDstRect(pipeId_postPictureGsc, &dstRect); |
| |
| CLOGD("DEBUG(%s):size (%d, %d, %d, %d %d %d)", __FUNCTION__, |
| srcRect.x, srcRect.y, srcRect.w, srcRect.h, srcRect.fullW, srcRect.fullH); |
| CLOGD("DEBUG(%s):size (%d, %d, %d, %d %d %d)", __FUNCTION__, |
| dstRect.x, dstRect.y, dstRect.w, dstRect.h, dstRect.fullW, dstRect.fullH); |
| |
| /* push frame to GSC pipe */ |
| m_pictureFrameFactory->setOutputFrameQToPipe(dstPostPictureGscQ, pipeId_postPictureGsc); |
| m_pictureFrameFactory->pushFrameToPipe(&newFrame, pipeId_postPictureGsc); |
| |
| ret = m_postPictureGscThread->run(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):couldn't run m_postPictureGscThread, ret(%d)", __FUNCTION__, __LINE__, ret); |
| return INVALID_OPERATION; |
| } |
| } |
| #endif |
| |
| currentSeriesShotMode = m_exynosCameraParameters->getSeriesShotMode(); |
| |
| #ifdef SAMSUNG_DEBLUR |
| if (m_exynosCameraParameters->getLDCaptureMode() == MULTI_SHOT_MODE_DEBLUR |
| && !getUseDeblurCaptureOn()) { |
| m_deblurCaptureCount = 0; |
| m_deblur_firstFrame = NULL; |
| m_deblur_secondFrame = NULL; |
| setUseDeblurCaptureOn(false); |
| m_exynosCameraParameters->setLDCaptureMode(MULTI_SHOT_MODE_NONE); |
| m_exynosCameraParameters->setLDCaptureCount(0); |
| m_exynosCameraParameters->setLDCaptureLLSValue(LLS_LEVEL_ZSL); |
| CLOGI("INFO(%s[%d]): deblur capture clear!", __FUNCTION__, __LINE__); |
| } |
| #endif |
| |
| /* Make compressed image */ |
| if (m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_COMPRESSED_IMAGE) || |
| m_exynosCameraParameters->getSeriesShotCount() > 0 || |
| m_hdrEnabled == true) { |
| |
| /* HDR callback */ |
| if (m_hdrEnabled == true || |
| currentSeriesShotMode == SERIES_SHOT_MODE_LLS || |
| currentSeriesShotMode == SERIES_SHOT_MODE_SIS || |
| m_exynosCameraParameters->getShotMode() == SHOT_MODE_FRONT_PANORAMA) { |
| #ifdef SR_CAPTURE |
| if(m_exynosCameraParameters->getSROn()) { |
| m_doSRCallbackFunc(newFrame); |
| } |
| #endif |
| CLOGD("DEBUG(%s[%d]): HDR callback", __FUNCTION__, __LINE__); |
| |
| /* send yuv image with jpeg callback */ |
| camera_memory_t *jpegCallbackHeap = NULL; |
| jpegCallbackHeap = m_getMemoryCb(gscReprocessingBuffer.fd[0], gscReprocessingBuffer.size[0], 1, m_callbackCookie); |
| if (!jpegCallbackHeap || jpegCallbackHeap->data == MAP_FAILED) { |
| CLOGE("ERR(%s[%d]):m_getMemoryCb(%d) fail", __FUNCTION__, __LINE__, gscReprocessingBuffer.size[0]); |
| goto CLEAN; |
| } |
| |
| setBit(&m_callbackState, CALLBACK_STATE_COMPRESSED_IMAGE, true); |
| m_dataCb(CAMERA_MSG_COMPRESSED_IMAGE, jpegCallbackHeap, 0, NULL, m_callbackCookie); |
| clearBit(&m_callbackState, CALLBACK_STATE_COMPRESSED_IMAGE, true); |
| |
| jpegCallbackHeap->release(jpegCallbackHeap); |
| |
| /* put GSC buffer */ |
| ret = m_putBuffers(bufferMgr, gscReprocessingBuffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):bufferMgr->putBuffers() fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId_gsc, ret); |
| goto CLEAN; |
| } |
| |
| m_jpegCounter.decCount(); |
| } else { |
| int retry = 0; |
| |
| /* 1. get wait available JPEG src buffer */ |
| do { |
| bufIndex = -2; |
| retry++; |
| |
| if (m_pictureEnabled == false) { |
| CLOGI("INFO(%s[%d]):m_pictureEnable is false", __FUNCTION__, __LINE__); |
| goto CLEAN; |
| } |
| if (m_jpegBufferMgr->getNumOfAvailableBuffer() > 0) |
| m_jpegBufferMgr->getBuffer(&bufIndex, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL, &jpegReprocessingBuffer); |
| |
| if (bufIndex < 0) { |
| usleep(WAITING_TIME); |
| |
| if (retry % 20 == 0) { |
| CLOGW("WRN(%s[%d]):retry JPEG getBuffer(%d) postPictureQ(%d), saveQ0(%d), saveQ1(%d), saveQ2(%d)", |
| __FUNCTION__, __LINE__, bufIndex, |
| m_postPictureQ->getSizeOfProcessQ(), |
| m_jpegSaveQ[JPEG_SAVE_THREAD0]->getSizeOfProcessQ(), |
| m_jpegSaveQ[JPEG_SAVE_THREAD1]->getSizeOfProcessQ(), |
| m_jpegSaveQ[JPEG_SAVE_THREAD2]->getSizeOfProcessQ()); |
| m_jpegBufferMgr->dump(); |
| } |
| } |
| /* this will retry until 300msec */ |
| } while (bufIndex < 0 && retry < (TOTAL_WAITING_TIME / WAITING_TIME) && m_stopBurstShot == false); |
| |
| if (bufIndex < 0) { |
| if (retry >= (TOTAL_WAITING_TIME / WAITING_TIME)) { |
| CLOGE("ERR(%s[%d]):getBuffer totally fail, retry(%d), m_stopBurstShot(%d)", |
| __FUNCTION__, __LINE__, retry, m_stopBurstShot); |
| /* HACK for debugging P150108-08143 */ |
| bufferMgr->printBufferState(); |
| android_printAssert(NULL, LOG_TAG, "BURST_SHOT_TIME_ASSERT(%s[%d]): unexpected error, get jpeg buffer failed, assert!!!!", __FUNCTION__, __LINE__); |
| } else { |
| CLOGD("DEBUG(%s[%d]):getBuffer stopped, retry(%d), m_stopBurstShot(%d)", |
| __FUNCTION__, __LINE__, retry, m_stopBurstShot); |
| } |
| ret = m_putBuffers(bufferMgr, gscReprocessingBuffer.index); |
| goto CLEAN; |
| } |
| |
| /* 2. setup Frame Entity */ |
| ret = m_setupEntity(pipeId_jpeg, newFrame, &gscReprocessingBuffer, &jpegReprocessingBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId_jpeg, ret); |
| goto CLEAN; |
| } |
| |
| /* 3. Q Set-up */ |
| m_pictureFrameFactory->setOutputFrameQToPipe(dstJpegReprocessingQ, pipeId_jpeg); |
| |
| #ifdef SAMSUNG_BD |
| if(m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_BURST) { |
| UTstr bdInfo = {NULL, 0}; |
| ret = m_BDbufferQ->waitAndPopProcessQ(&bdInfo); |
| if(ret == TIMED_OUT || ret < 0) { |
| CLOGE("[BD](%s)(%d):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| else { |
| CLOGD("[BD](%s[%d]): Pop the buffer(size: %d)", __FUNCTION__, __LINE__, bdInfo.size); |
| m_exynosCameraParameters->setBlurInfo(bdInfo.data, bdInfo.size); |
| } |
| } |
| #endif |
| |
| /* 4. push the newFrame to pipe */ |
| m_pictureFrameFactory->pushFrameToPipe(&newFrame, pipeId_jpeg); |
| |
| /* 5. wait outputQ */ |
| CLOGI("INFO(%s[%d]):wait Jpeg output", __FUNCTION__, __LINE__); |
| while (retryCountJPEG > 0) { |
| ret = dstJpegReprocessingQ->waitAndPopProcessQ(&newFrame); |
| if (ret == TIMED_OUT) { |
| CLOGW("WRN(%s)(%d):wait and pop timeout, ret(%d)", __FUNCTION__, __LINE__, ret); |
| m_pictureFrameFactory->startThread(pipeId_jpeg); |
| } else if (ret < 0) { |
| CLOGE("ERR(%s)(%d):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| /* TODO: doing exception handling */ |
| goto CLEAN; |
| } else { |
| break; |
| } |
| retryCountJPEG--; |
| } |
| |
| if (newFrame == NULL) { |
| CLOGE("ERR(%s[%d]):newFrame is NULL", __FUNCTION__, __LINE__); |
| goto CLEAN; |
| } |
| /* |
| * When Non-reprocessing scenario does not setEntityState, |
| * because Non-reprocessing scenario share preview and capture frames |
| */ |
| if (m_exynosCameraParameters->isReprocessing() == true) { |
| ret = newFrame->setEntityState(pipeId_jpeg, ENTITY_STATE_COMPLETE); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setEntityState(ENTITY_STATE_COMPLETE) fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId_jpeg, ret); |
| return ret; |
| } |
| } |
| |
| #if defined(SAMSUNG_DEBLUR) || defined(SAMSUNG_LLS_DEBLUR) |
| if (m_exynosCameraParameters->getLDCaptureMode() |
| && m_exynosCameraParameters->getIsThumbnailCallbackOn()) { |
| if (m_postPictureGscThread->isRunning()) { |
| m_postPictureGscThread->join(); |
| CLOGD("DEBUG(%s[%d]): m_postPictureGscThread join", __FUNCTION__, __LINE__); |
| } |
| } |
| #endif |
| |
| /* put GSC buffer */ |
| ret = m_putBuffers(bufferMgr, gscReprocessingBuffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):bufferMgr->putBuffers() fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId_gsc, ret); |
| goto CLEAN; |
| } |
| |
| int jpegOutputSize = newFrame->getJpegSize(); |
| CLOGI("INFO(%s[%d]):Jpeg output done, jpeg size(%d)", __FUNCTION__, __LINE__, jpegOutputSize); |
| |
| if (jpegOutputSize <= 0) { |
| CLOGW("WRN(%s[%d]): jpegOutput size(%d) is invalid", __FUNCTION__, __LINE__, jpegOutputSize); |
| jpegOutputSize = jpegReprocessingBuffer.size[0]; |
| } |
| |
| jpegReprocessingBuffer.size[0] = jpegOutputSize; |
| |
| #if 0 // SAMSUNG_MAGICSHOT |
| if ((m_exynosCameraParameters->getShotMode() == SHOT_MODE_MAGIC) && |
| (m_exynosCameraParameters->isReprocessing() == true)) { |
| m_postPictureGscThread->join(); |
| } |
| #endif |
| |
| /* push postProcess to call CAMERA_MSG_COMPRESSED_IMAGE */ |
| jpeg_callback_buffer_t jpegCallbackBuf; |
| jpegCallbackBuf.buffer = jpegReprocessingBuffer; |
| #ifdef BURST_CAPTURE |
| m_burstCaptureCallbackCount++; |
| CLOGI("INFO(%s[%d]): burstCaptureCallbackCount(%d)", __FUNCTION__, __LINE__, m_burstCaptureCallbackCount); |
| #endif |
| retry: |
| if ((m_exynosCameraParameters->getSeriesShotCount() > 0) |
| #ifdef SAMSUNG_MAGICSHOT |
| && !((m_exynosCameraParameters->getShotMode() == SHOT_MODE_MAGIC) && (m_burstCaptureCallbackCount > m_magicshotMaxCount)) |
| #endif |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| && (m_exynosCameraParameters->getSeriesShotMode() != SERIES_SHOT_MODE_ONE_SECOND_BURST) |
| #endif |
| ) { |
| int threadNum = 0; |
| |
| if (m_burst[JPEG_SAVE_THREAD0] == false && m_jpegSaveThread[JPEG_SAVE_THREAD0]->isRunning() == false) { |
| threadNum = JPEG_SAVE_THREAD0; |
| } else if (m_burst[JPEG_SAVE_THREAD1] == false && m_jpegSaveThread[JPEG_SAVE_THREAD1]->isRunning() == false) { |
| threadNum = JPEG_SAVE_THREAD1; |
| } else if (m_burst[JPEG_SAVE_THREAD2] == false && m_jpegSaveThread[JPEG_SAVE_THREAD2]->isRunning() == false) { |
| threadNum = JPEG_SAVE_THREAD2; |
| } else { |
| CLOGW("WARN(%s[%d]): wait for available save thread, thread running(%d, %d, %d,)", |
| __FUNCTION__, __LINE__, |
| m_jpegSaveThread[JPEG_SAVE_THREAD0]->isRunning(), |
| m_jpegSaveThread[JPEG_SAVE_THREAD1]->isRunning(), |
| m_jpegSaveThread[JPEG_SAVE_THREAD2]->isRunning()); |
| usleep(WAITING_TIME * 10); |
| goto retry; |
| } |
| |
| m_burst[threadNum] = true; |
| ret = m_jpegSaveThread[threadNum]->run(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): m_jpegSaveThread%d run fail, ret(%d)", __FUNCTION__, __LINE__, threadNum, ret); |
| m_burst[threadNum] = false; |
| m_running[threadNum] = false; |
| goto retry; |
| } |
| |
| jpegCallbackBuf.callbackNumber = m_burstCaptureCallbackCount; |
| m_jpegSaveQ[threadNum]->pushProcessQ(&jpegCallbackBuf); |
| } else { |
| jpegCallbackBuf.callbackNumber = 0; |
| m_jpegCallbackQ->pushProcessQ(&jpegCallbackBuf); |
| } |
| |
| m_jpegCounter.decCount(); |
| } |
| } else { |
| CLOGD("DEBUG(%s[%d]): Disabled compressed image", __FUNCTION__, __LINE__); |
| |
| #if defined(SAMSUNG_DEBLUR) || defined(SAMSUNG_LLS_DEBLUR) |
| if (m_exynosCameraParameters->getLDCaptureMode() && m_exynosCameraParameters->getIsThumbnailCallbackOn()) { |
| if (m_postPictureGscThread->isRunning()) { |
| m_postPictureGscThread->join(); |
| CLOGD("DEBUG(%s[%d]): m_postPictureGscThread join", __FUNCTION__, __LINE__); |
| } |
| } |
| #endif |
| |
| /* put GSC buffer */ |
| ret = m_putBuffers(bufferMgr, gscReprocessingBuffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):bufferMgr->putBuffers() fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId_gsc, ret); |
| goto CLEAN; |
| } |
| |
| m_jpegCounter.decCount(); |
| } |
| |
| if (newFrame != NULL) { |
| newFrame->printEntity(); |
| newFrame->frameUnlock(); |
| ret = m_removeFrameFromList(&m_postProcessList, newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):remove frame from processList fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| |
| #ifdef LLS_REPROCESSING |
| if (m_captureSelector->getIsLastFrame() == true) |
| #endif |
| { |
| CLOGD("DEBUG(%s[%d]): Picture frame delete(%d)", __FUNCTION__, __LINE__, newFrame->getFrameCount()); |
| newFrame->decRef(); |
| m_frameMgr->deleteFrame(newFrame); |
| newFrame = NULL; |
| } |
| } |
| |
| CLOGI("INFO(%s[%d]):postPicture thread complete, remaining count(%d)", __FUNCTION__, __LINE__, m_jpegCounter.getCount()); |
| |
| if (m_jpegCounter.getCount() <= 0) { |
| if (m_hdrEnabled == true) { |
| CLOGI("INFO(%s[%d]): End of HDR capture!", __FUNCTION__, __LINE__); |
| m_hdrEnabled = false; |
| m_pictureEnabled = false; |
| } |
| if (currentSeriesShotMode == SERIES_SHOT_MODE_LLS || |
| currentSeriesShotMode == SERIES_SHOT_MODE_SIS) { |
| CLOGI("INFO(%s[%d]): End of LLS/SIS capture!", __FUNCTION__, __LINE__); |
| m_pictureEnabled = false; |
| |
| #ifdef SAMSUNG_DNG |
| if (m_exynosCameraParameters->getDNGCaptureModeOn()) { |
| int waitCount = 5; |
| while (m_previewFrameFactory->getRunningFrameCount(PIPE_FLITE) != 0 && 0 < waitCount) { |
| CLOGD("DNG(%s[%d]): wait flite dqbuffer count(%d)", |
| __FUNCTION__, __LINE__, m_previewFrameFactory->getRunningFrameCount(PIPE_FLITE)); |
| usleep(30000); |
| waitCount--; |
| } |
| |
| if (m_exynosCameraParameters->getCheckMultiFrame()) { |
| CLOGE("[DNG](%s[%d]):PIPE_FLITE stop", __FUNCTION__, __LINE__); |
| m_exynosCameraParameters->setUseDNGCapture(false); |
| m_exynosCameraParameters->setCheckMultiFrame(false); |
| m_previewFrameFactory->stopThread(PIPE_FLITE); |
| } |
| |
| CLOGD("DNG(%s[%d]): reset m_fliteBuffer buffers", __FUNCTION__, __LINE__); |
| m_fliteBufferMgr->resetBuffers(); |
| } |
| #endif |
| } |
| |
| if(m_exynosCameraParameters->getShotMode() == SHOT_MODE_FRONT_PANORAMA) { |
| CLOGI("INFO(%s[%d]): End of wideselfie capture!", __FUNCTION__, __LINE__); |
| m_pictureEnabled = false; |
| } |
| |
| CLOGD("DEBUG(%s[%d]): free gsc buffers", __FUNCTION__, __LINE__); |
| m_gscBufferMgr->resetBuffers(); |
| |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| if (!(currentSeriesShotMode == SERIES_SHOT_MODE_ONE_SECOND_BURST || |
| currentSeriesShotMode == SERIES_SHOT_MODE_BURST)) |
| #else |
| if (currentSeriesShotMode != SERIES_SHOT_MODE_BURST) |
| #endif |
| { |
| CLOGD("DEBUG(%s[%d]): clearList postProcessList, series shot mode(%d)", __FUNCTION__, __LINE__, currentSeriesShotMode); |
| if (m_clearList(&m_postProcessList) < 0) { |
| CLOGE("ERR(%s):m_clearList fail", __FUNCTION__); |
| } |
| } |
| } |
| |
| if (m_exynosCameraParameters->getScalableSensorMode()) { |
| m_scalableSensorMgr.setMode(EXYNOS_CAMERA_SCALABLE_CHANGING); |
| ret = m_restartPreviewInternal(); |
| if (ret < 0) |
| CLOGE("(%s[%d]): restart preview internal fail", __FUNCTION__, __LINE__); |
| m_scalableSensorMgr.setMode(EXYNOS_CAMERA_SCALABLE_NONE); |
| } |
| |
| CLEAN: |
| if (newFrame != NULL) { |
| CLOGD("DEBUG(%s[%d]): Picture frame delete(%d)", __FUNCTION__, __LINE__, newFrame->getFrameCount()); |
| newFrame->decRef(); |
| m_frameMgr->deleteFrame(newFrame); |
| newFrame = NULL; |
| } |
| |
| /* HACK: Sometimes, m_postPictureThread is finished without waiting the last picture */ |
| int waitCount = 5; |
| while (m_postPictureQ->getSizeOfProcessQ() == 0 && 0 < waitCount) { |
| usleep(10000); |
| waitCount--; |
| } |
| |
| if (m_postPictureQ->getSizeOfProcessQ() > 0 || |
| currentSeriesShotMode != SERIES_SHOT_MODE_NONE) { |
| CLOGD("DEBUG(%s[%d]):postPicture thread will run again. currentSeriesShotMode(%d), postPictureQ size(%d)", |
| __func__, __LINE__, currentSeriesShotMode, m_postPictureQ->getSizeOfProcessQ()); |
| loop = true; |
| } |
| |
| return loop; |
| } |
| |
| bool ExynosCamera::m_jpegSaveThreadFunc(void) |
| { |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| CLOGI("DEBUG(%s[%d]):", __FUNCTION__, __LINE__); |
| |
| int ret = 0; |
| int loop = false; |
| int curThreadNum = -1; |
| char burstFilePath[CAMERA_FILE_PATH_SIZE]; |
| #ifdef BURST_CAPTURE |
| int fd = -1; |
| #endif |
| |
| jpeg_callback_buffer_t jpegCallbackBuf; |
| ExynosCameraBuffer jpegSaveBuffer; |
| int seriesShotNumber = -1; |
| // camera_memory_t *jpegCallbackHeap = NULL; |
| |
| for (int threadNum = JPEG_SAVE_THREAD0; threadNum < JPEG_SAVE_THREAD_MAX_COUNT; threadNum++) { |
| if (m_burst[threadNum] == true && m_running[threadNum] == false) { |
| m_running[threadNum] = true; |
| curThreadNum = threadNum; |
| if (m_jpegSaveQ[curThreadNum]->waitAndPopProcessQ(&jpegCallbackBuf) < 0) { |
| CLOGE("ERR(%s[%d]):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto done; |
| } |
| break; |
| } |
| } |
| |
| if (curThreadNum < 0 || curThreadNum > JPEG_SAVE_THREAD2) { |
| CLOGE("ERR(%s[%d]): invalid thrad num (%d)", __FUNCTION__, __LINE__, curThreadNum); |
| goto done; |
| } |
| |
| jpegSaveBuffer = jpegCallbackBuf.buffer; |
| seriesShotNumber = jpegCallbackBuf.callbackNumber; |
| |
| #ifdef BURST_CAPTURE |
| if (m_exynosCameraParameters->getSeriesShotCount() > 0) { |
| |
| int seriesShotSaveLocation = m_exynosCameraParameters->getSeriesShotSaveLocation(); |
| |
| if (seriesShotSaveLocation == BURST_SAVE_CALLBACK) { |
| jpegCallbackBuf.buffer = jpegSaveBuffer; |
| jpegCallbackBuf.callbackNumber = 0; |
| m_jpegCallbackQ->pushProcessQ(&jpegCallbackBuf); |
| goto done; |
| } else { |
| memset(burstFilePath, 0, sizeof(burstFilePath)); |
| |
| m_burstCaptureCallbackCountLock.lock(); |
| #if defined(SAMSUNG_INF_BURST) |
| { |
| time_t rawtime; |
| struct tm *timeinfo; |
| |
| time(&rawtime); |
| timeinfo = localtime(&rawtime); |
| if(seriesShotNumber == 1) { |
| strftime(m_burstTime, 20, "%Y%m%d_%H%M%S", timeinfo); |
| } |
| else { |
| /* We don't do anything in this time */ |
| } |
| |
| snprintf(burstFilePath, sizeof(burstFilePath), "%s%s_%03d.jpg", |
| m_burstSavePath, m_burstTime, seriesShotNumber); |
| } |
| #else |
| snprintf(burstFilePath, sizeof(burstFilePath), "%sBurst%02d.jpg", m_burstSavePath, seriesShotNumber); |
| #endif |
| m_burstCaptureCallbackCountLock.unlock(); |
| |
| CLOGD("DEBUG(%s[%d]):%s fd:%d jpegSize : %d", __FUNCTION__, __LINE__, burstFilePath, jpegSaveBuffer.fd[0], jpegSaveBuffer.size[0]); |
| |
| m_burstCaptureSaveLock.lock(); |
| |
| m_burstSaveTimer.start(); |
| |
| if(m_FileSaveFunc(burstFilePath, &jpegSaveBuffer) == false) { |
| m_burstCaptureSaveLock.unlock(); |
| CLOGE("ERR(%s[%d]): FILE save ERROR", __FUNCTION__, __LINE__); |
| goto done; |
| } |
| |
| m_burstCaptureSaveLock.unlock(); |
| |
| m_burstSaveTimer.stop(); |
| m_burstSaveTimerTime = m_burstSaveTimer.durationUsecs(); |
| if (m_burstSaveTimerTime > (m_burstDuration - 33000)) { |
| m_burstDuration += (int)((m_burstSaveTimerTime - m_burstDuration + 33000) / 33000) * 33000; |
| CLOGD("Increase burst duration = %d", m_burstDuration); |
| } |
| |
| CLOGD("DEBUG(%s[%d]):m_burstSaveTimerTime : %d msec, path(%s)", __FUNCTION__, __LINE__, (int)m_burstSaveTimerTime / 1000, burstFilePath); |
| } |
| jpegCallbackBuf.buffer = jpegSaveBuffer; |
| jpegCallbackBuf.callbackNumber = seriesShotNumber; |
| m_jpegCallbackQ->pushProcessQ(&jpegCallbackBuf); |
| } else |
| #endif |
| { |
| jpegCallbackBuf.buffer = jpegSaveBuffer; |
| jpegCallbackBuf.callbackNumber = 0; |
| m_jpegCallbackQ->pushProcessQ(&jpegCallbackBuf); |
| } |
| |
| done: |
| /* |
| if (jpegCallbackHeap == NULL || |
| jpegCallbackHeap->data == MAP_FAILED) { |
| |
| if (jpegCallbackHeap) { |
| jpegCallbackHeap->release(jpegCallbackHeap); |
| jpegCallbackHeap = NULL; |
| } |
| |
| m_notifyCb(CAMERA_MSG_ERROR, -1, 0, m_callbackCookie); |
| } |
| */ |
| if (JPEG_SAVE_THREAD0 <= curThreadNum && curThreadNum < JPEG_SAVE_THREAD_MAX_COUNT) { |
| m_burst[curThreadNum] = false; |
| m_running[curThreadNum] = false; |
| } |
| |
| CLOGI("INFO(%s[%d]):saving jpeg buffer done", __FUNCTION__, __LINE__); |
| |
| /* one shot */ |
| return false; |
| } |
| |
| bool ExynosCamera::m_jpegCallbackThreadFunc(void) |
| { |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| CLOGI("DEBUG(%s[%d]):", __FUNCTION__, __LINE__); |
| |
| int ret = 0; |
| int retry = 0, maxRetry = 0; |
| int loop = false; |
| int seriesShotNumber = -1; |
| int currentSeriesShotMode = 0; |
| |
| jpeg_callback_buffer_t jpegCallbackBuf; |
| ExynosCameraBuffer jpegCallbackBuffer; |
| ExynosCameraBuffer postviewCallbackBuffer; |
| camera_memory_t *jpegCallbackHeap = NULL; |
| camera_memory_t *postviewCallbackHeap = NULL; |
| ExynosCameraBufferManager *postviewBufferMgr = NULL; |
| |
| jpegCallbackBuffer.index = -2; |
| jpegCallbackBuf.callbackNumber = -1; |
| |
| postviewCallbackBuffer.index = -2; |
| |
| ExynosCameraActivityFlash *m_flashMgr = m_exynosCameraActivityControl->getFlashMgr(); |
| currentSeriesShotMode = m_exynosCameraParameters->getSeriesShotMode(); |
| |
| if (m_flashMgr->getNeedFlash() == true) { |
| maxRetry = TOTAL_FLASH_WATING_COUNT; |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| } else if (currentSeriesShotMode == SERIES_SHOT_MODE_ONE_SECOND_BURST) { |
| maxRetry = ONE_SECOND_BURST_CAPTURE_MAX_RETRY; |
| #endif |
| } else { |
| maxRetry = TOTAL_WAITING_COUNT; |
| } |
| |
| #ifdef BURST_CAPTURE |
| if (currentSeriesShotMode == SERIES_SHOT_MODE_BURST) { |
| if (m_burstShutterLocation == BURST_SHUTTER_JPEGCB) { |
| m_shutterCallbackThread->join(); |
| CLOGD("Burst Shutter callback start(%s)(%d)", __FUNCTION__, __LINE__); |
| m_shutterCallbackThreadFunc(); |
| CLOGD("Burst Shutter callback end(%s)(%d)", __FUNCTION__, __LINE__); |
| } else if (m_burstShutterLocation == BURST_SHUTTER_PREPICTURE_DONE) { |
| m_burstShutterLocation = BURST_SHUTTER_JPEGCB; |
| } |
| } |
| #endif |
| |
| m_getBufferManager(PIPE_GSC_REPROCESSING3, &postviewBufferMgr, DST_BUFFER_DIRECTION); |
| if ((m_exynosCameraParameters->getIsThumbnailCallbackOn() |
| #if defined(SAMSUNG_DEBLUR) || defined(SAMSUNG_LLS_DEBLUR) |
| || m_exynosCameraParameters->getLDCaptureMode() |
| #endif |
| ) |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| && currentSeriesShotMode != SERIES_SHOT_MODE_ONE_SECOND_BURST |
| #endif |
| && m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_POSTVIEW_FRAME)) { |
| /* One second burst will get thumbnail RGB after get jpegcallbackheap */ |
| if (m_cancelPicture) { |
| loop = false; |
| goto CLEAN; |
| } |
| |
| do { |
| ret = m_postviewCallbackQ->waitAndPopProcessQ(&postviewCallbackBuffer); |
| if (ret < 0) { |
| retry++; |
| CLOGW("WARN(%s[%d]):postviewCallbackQ pop fail, retry(%d)", __FUNCTION__, __LINE__, retry); |
| } |
| } while (ret < 0 && retry < maxRetry && |
| m_flagThreadStop != true && |
| m_stopBurstShot == false && |
| !m_cancelPicture); |
| |
| postviewCallbackHeap = m_getMemoryCb(postviewCallbackBuffer.fd[0], |
| postviewCallbackBuffer.size[0], |
| 1, m_callbackCookie); |
| |
| if (!postviewCallbackHeap || postviewCallbackHeap->data == MAP_FAILED) { |
| CLOGE("ERR(%s[%d]):get postviewCallbackHeap(fd(%d), size(%d)) fail", |
| __FUNCTION__, __LINE__, postviewCallbackBuffer.fd[0], postviewCallbackBuffer.size[0]); |
| loop = true; |
| goto CLEAN; |
| } |
| |
| if (!m_cancelPicture) { |
| CLOGD("thumbnail POSTVIEW callback start(%s)(%d)", __FUNCTION__, __LINE__); |
| setBit(&m_callbackState, CALLBACK_STATE_POSTVIEW_FRAME, true); |
| m_dataCb(CAMERA_MSG_POSTVIEW_FRAME, postviewCallbackHeap, 0, NULL, m_callbackCookie); |
| clearBit(&m_callbackState, CALLBACK_STATE_POSTVIEW_FRAME, true); |
| CLOGD("thumbnail POSTVIEW callback end(%s)(%d)", __FUNCTION__, __LINE__); |
| } |
| postviewCallbackHeap->release(postviewCallbackHeap); |
| } |
| |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| if (currentSeriesShotMode == SERIES_SHOT_MODE_ONE_SECOND_BURST) { |
| retry = 0; |
| /* For launch COMPRESSED m_dataCb() faster*/ |
| do { |
| if (m_one_second_burst_capture && m_one_second_jpegCallbackHeap != NULL) { |
| /* If there's saved jpegCallbackHeap */ |
| CLOGD("DEBUG(%s[%d]):ONE SECOND CAPTURE coming.", __FUNCTION__, __LINE__); |
| ret = 0; |
| break; |
| } |
| ret = m_jpegCallbackQ->popProcessQ(&jpegCallbackBuf); |
| if (ret < 0) { |
| /* If there's no saved jpegCallbackHeap, ret value will smaller than 0 |
| This will launch "goto CLEAN" */ |
| retry++; |
| CLOGW("WARN(%s[%d]):jpegCallbackQ pop fail, retry(%d)", __FUNCTION__, __LINE__, retry); |
| usleep(ONE_SECOND_BURST_CAPTURE_RETRY_DELAY); |
| } |
| } while(ret < 0 && retry < maxRetry && m_jpegCounter.getCount() > 0 && m_stopBurstShot == false); |
| |
| if (m_stopBurstShot) |
| goto CLEAN; |
| } else |
| #endif |
| { |
| if (m_cancelPicture) { |
| loop = false; |
| goto CLEAN; |
| } |
| |
| do { |
| ret = m_jpegCallbackQ->waitAndPopProcessQ(&jpegCallbackBuf); |
| if (ret < 0) { |
| retry++; |
| CLOGW("WARN(%s[%d]):jpegCallbackQ pop fail, retry(%d)", __FUNCTION__, __LINE__, retry); |
| } |
| } while(ret < 0 && retry < maxRetry && m_jpegCounter.getCount() > 0 && !m_cancelPicture); |
| } |
| |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| if (currentSeriesShotMode == SERIES_SHOT_MODE_ONE_SECOND_BURST |
| && m_exynosCameraParameters->getIsThumbnailCallbackOn() |
| && jpegCallbackBuf.callbackNumber != -1) { |
| do { |
| ret = m_postviewCallbackQ->waitAndPopProcessQ(&postviewCallbackBuffer); |
| if (ret < 0) { |
| retry++; |
| CLOGW("WARN(%s[%d]):postviewCallbackQ pop fail, retry(%d)", __FUNCTION__, __LINE__, retry); |
| } |
| } while (ret < 0 && retry < maxRetry && m_flagThreadStop != true && m_stopBurstShot == false); |
| |
| postviewCallbackHeap = m_getMemoryCb(postviewCallbackBuffer.fd[0], postviewCallbackBuffer.size[0], 1, m_callbackCookie); |
| |
| if (!postviewCallbackHeap || postviewCallbackHeap->data == MAP_FAILED) { |
| CLOGE("ERR(%s[%d]): get postviewCallbackHeap(%d) fail", __FUNCTION__, __LINE__); |
| loop = true; |
| goto CLEAN; |
| } |
| } |
| #endif |
| |
| m_captureLock.lock(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| loop = true; |
| goto CLEAN; |
| } |
| |
| if (jpegCallbackBuf.callbackNumber != -1) { |
| jpegCallbackBuffer = jpegCallbackBuf.buffer; |
| seriesShotNumber = jpegCallbackBuf.callbackNumber; |
| } |
| |
| CLOGD("DEBUG(%s[%d]):jpeg calllback is start", __FUNCTION__, __LINE__); |
| |
| /* Make compressed image */ |
| if (m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_COMPRESSED_IMAGE) || |
| m_exynosCameraParameters->getSeriesShotCount() > 0) { |
| if (jpegCallbackBuf.callbackNumber != -1) { |
| jpegCallbackHeap = m_getJpegCallbackHeap(jpegCallbackBuffer, seriesShotNumber); |
| } |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| if (currentSeriesShotMode == SERIES_SHOT_MODE_ONE_SECOND_BURST) { |
| if (jpegCallbackHeap != NULL) { |
| if (m_one_second_jpegCallbackHeap != NULL) { |
| /* if last jpegCallbackHeap is remained */ |
| m_one_second_jpegCallbackHeap->release(m_one_second_jpegCallbackHeap); |
| } |
| /* Save last jpegCallbackHeap */ |
| m_one_second_jpegCallbackHeap = jpegCallbackHeap; |
| } else { |
| /* Ready for COMPRESSED m_dataCb() */ |
| jpegCallbackHeap = m_one_second_jpegCallbackHeap; |
| } |
| if (m_exynosCameraParameters->getIsThumbnailCallbackOn()) { |
| if (postviewCallbackHeap != NULL) { |
| if (m_one_second_postviewCallbackHeap != NULL) { |
| m_one_second_postviewCallbackHeap->release(m_one_second_postviewCallbackHeap); |
| } |
| m_one_second_postviewCallbackHeap = postviewCallbackHeap; |
| } else { |
| postviewCallbackHeap = m_one_second_postviewCallbackHeap; |
| } |
| } |
| } |
| #endif |
| if (jpegCallbackHeap == NULL) { |
| CLOGE("ERR(%s[%d]):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| /* TODO: doing exception handling */ |
| android_printAssert(NULL, LOG_TAG, "Cannot recoverable, assert!!!!"); |
| } |
| |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| if (currentSeriesShotMode != SERIES_SHOT_MODE_ONE_SECOND_BURST || |
| (currentSeriesShotMode == SERIES_SHOT_MODE_ONE_SECOND_BURST && m_one_second_burst_capture)) { |
| if (currentSeriesShotMode == SERIES_SHOT_MODE_ONE_SECOND_BURST) { |
| m_one_second_burst_capture = false; |
| if (m_burstShutterLocation == BURST_SHUTTER_JPEGCB) { |
| m_shutterCallbackThread->join(); |
| CLOGD("One Second Shutter callback start(%s)(%d)", __FUNCTION__, __LINE__); |
| m_shutterCallbackThreadFunc(); |
| CLOGD("One Second Shutter callback end(%s)(%d)", __FUNCTION__, __LINE__); |
| } else if (m_burstShutterLocation == BURST_SHUTTER_PREPICTURE_DONE) { |
| m_burstShutterLocation = BURST_SHUTTER_JPEGCB; |
| } |
| if (m_exynosCameraParameters->getIsThumbnailCallbackOn()) { |
| if (m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_POSTVIEW_FRAME)) { |
| CLOGD("thumbnail POSTVIEW callback start(%s)(%d)", __FUNCTION__, __LINE__); |
| setBit(&m_callbackState, CALLBACK_STATE_POSTVIEW_FRAME, true); |
| m_dataCb(CAMERA_MSG_POSTVIEW_FRAME, postviewCallbackHeap, 0, NULL, m_callbackCookie); |
| clearBit(&m_callbackState, CALLBACK_STATE_POSTVIEW_FRAME, true); |
| CLOGD("thumbnail POSTVIEW callback end(%s)(%d)", __FUNCTION__, __LINE__); |
| } |
| if (m_one_second_postviewCallbackHeap != NULL) { |
| /* release saved buffer when COMPRESSED m_dataCb() called. */ |
| m_one_second_postviewCallbackHeap->release(m_one_second_postviewCallbackHeap); |
| m_one_second_postviewCallbackHeap = NULL; |
| } |
| } |
| CLOGD("DEBUG(%s[%d]): before compressed - TimeCheck", __FUNCTION__, __LINE__); |
| } |
| #endif |
| if (!m_cancelPicture) { |
| setBit(&m_callbackState, CALLBACK_STATE_COMPRESSED_IMAGE, true); |
| m_dataCb(CAMERA_MSG_COMPRESSED_IMAGE, jpegCallbackHeap, 0, NULL, m_callbackCookie); |
| clearBit(&m_callbackState, CALLBACK_STATE_COMPRESSED_IMAGE, true); |
| CLOGD("DEBUG(%s[%d]): CAMERA_MSG_COMPRESSED_IMAGE callback (%d)", |
| __FUNCTION__, __LINE__, m_burstCaptureCallbackCount); |
| } |
| |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| if (currentSeriesShotMode == SERIES_SHOT_MODE_ONE_SECOND_BURST) { |
| CLOGD("DEBUG(%s[%d]): After compressed - TimeCheck", __FUNCTION__, __LINE__); |
| if (m_one_second_jpegCallbackHeap != NULL) { |
| /* release saved buffer when COMPRESSED m_dataCb() called. */ |
| m_one_second_jpegCallbackHeap->release(m_one_second_jpegCallbackHeap); |
| m_one_second_jpegCallbackHeap = NULL; |
| } |
| } |
| } |
| #endif |
| if (jpegCallbackBuf.callbackNumber != -1) { |
| /* put JPEG callback buffer */ |
| if (m_jpegBufferMgr->putBuffer(jpegCallbackBuffer.index, EXYNOS_CAMERA_BUFFER_POSITION_NONE) != NO_ERROR) |
| CLOGE("ERR(%s[%d]):putBuffer(%d) fail", __FUNCTION__, __LINE__, jpegCallbackBuffer.index); |
| } |
| |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| /* One second burst operation will release m_one_second_jpegCallbackHeap */ |
| if (currentSeriesShotMode != SERIES_SHOT_MODE_ONE_SECOND_BURST) |
| #endif |
| jpegCallbackHeap->release(jpegCallbackHeap); |
| } else { |
| CLOGD("DEBUG(%s[%d]): Disabled compressed image", __FUNCTION__, __LINE__); |
| } |
| |
| CLEAN: |
| CLOGI("INFO(%s[%d]):jpeg callback thread complete, remaining count(%d)", __FUNCTION__, __LINE__, m_takePictureCounter.getCount()); |
| |
| if (postviewCallbackBuffer.index != -2) { |
| CLOGD("DEBUG(%s[%d]): put dst(%d)", __FUNCTION__, __LINE__, postviewCallbackBuffer.index); |
| m_putBuffers(postviewBufferMgr, postviewCallbackBuffer.index); |
| } |
| |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| if (currentSeriesShotMode == SERIES_SHOT_MODE_ONE_SECOND_BURST) { |
| m_jpegCallbackCounter.decCount(); |
| CLOGD("DEBUG(%s[%d]):ONE SECOND BURST remaining count(%d)", __FUNCTION__, __LINE__, m_jpegCallbackCounter.getCount()); |
| if (m_jpegCallbackCounter.getCount() <= 1) { |
| if (m_one_second_burst_capture) { |
| loop = true; |
| m_jpegCallbackCounter.setCount(2); |
| m_reprocessingCounter.setCount(2); |
| m_jpegCounter.setCount(2); |
| m_pictureCounter.setCount(2); |
| CLOGD("DEBUG(%s[%d]):Waiting once more...", __FUNCTION__, __LINE__); |
| } else { |
| loop = false; |
| m_clearOneSecondBurst(true); |
| } |
| } else { |
| loop = true; |
| } |
| } |
| #endif |
| |
| if (m_takePictureCounter.getCount() == 0) { |
| m_pictureEnabled = false; |
| loop = false; |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| /* m_clearJpegCallbackThread() already called in m_clearOneSecondBurst() */ |
| if (currentSeriesShotMode != SERIES_SHOT_MODE_ONE_SECOND_BURST) |
| #endif |
| m_clearJpegCallbackThread(true); |
| m_captureLock.unlock(); |
| } else { |
| m_captureLock.unlock(); |
| } |
| |
| return loop; |
| } |
| |
| void ExynosCamera::m_clearJpegCallbackThread(bool callFromJpeg) |
| { |
| jpeg_callback_buffer_t jpegCallbackBuf; |
| ExynosCameraBuffer postviewCallbackBuffer; |
| ExynosCameraBuffer thumbnailCallbackBuffer; |
| ExynosCameraBuffer jpegCallbackBuffer; |
| ExynosCameraBufferManager *postviewBufferMgr = NULL; |
| ExynosCameraBufferManager *thumbnailBufferMgr = NULL; |
| |
| CLOGI("INFO(%s[%d]): takePicture disabled, takePicture callback done takePictureCounter(%d)", |
| __FUNCTION__, __LINE__, m_takePictureCounter.getCount()); |
| m_pictureEnabled = false; |
| |
| if (m_exynosCameraParameters->getUseDynamicScc() == true) { |
| CLOGD("DEBUG(%s[%d]): Use dynamic bayer", __FUNCTION__, __LINE__); |
| if (isOwnScc(getCameraId()) == true) |
| m_previewFrameFactory->setRequestSCC(false); |
| else |
| m_previewFrameFactory->setRequestISPC(false); |
| } |
| |
| #ifdef SAMSUNG_DEBLUR |
| if (m_exynosCameraParameters->getLDCaptureMode() == MULTI_SHOT_MODE_DEBLUR |
| && getUseDeblurCaptureOn()) { |
| m_deblurCaptureCount = 0; |
| m_deblur_firstFrame = NULL; |
| m_deblur_secondFrame = NULL; |
| setUseDeblurCaptureOn(false); |
| m_exynosCameraParameters->setLDCaptureMode(MULTI_SHOT_MODE_NONE); |
| m_exynosCameraParameters->setLDCaptureCount(0); |
| m_exynosCameraParameters->setLDCaptureLLSValue(LLS_LEVEL_ZSL); |
| CLOGI("INFO(%s[%d]): deblur capture clear!", __FUNCTION__, __LINE__); |
| } |
| #endif |
| |
| #ifdef SAMSUNG_LLS_DEBLUR |
| if(m_exynosCameraParameters->getLDCaptureMode()) { |
| m_LDCaptureCount = 0; |
| |
| for (int i = 0; i < MAX_LD_CAPTURE_COUNT; i++) { |
| m_LDBufIndex[i] = 0; |
| } |
| |
| m_exynosCameraParameters->setLDCaptureMode(MULTI_SHOT_MODE_NONE); |
| m_exynosCameraParameters->setLDCaptureCount(0); |
| m_exynosCameraParameters->setLDCaptureLLSValue(LLS_LEVEL_ZSL); |
| #ifdef SET_LLS_CAPTURE_SETFILE |
| m_exynosCameraParameters->setLLSCaptureOn(false); |
| #endif |
| } |
| #endif |
| |
| m_prePictureThread->requestExit(); |
| m_pictureThread->requestExit(); |
| #ifdef SAMSUNG_LLS_DEBLUR |
| m_LDCaptureThread->requestExit(); |
| #endif |
| m_postPictureGscThread->requestExit(); |
| #ifdef SAMSUNG_DEBLUR |
| m_detectDeblurCaptureThread->requestExit(); |
| m_deblurCaptureThread->requestExit(); |
| #endif |
| m_ThumbnailCallbackThread->requestExit(); |
| #ifdef SAMSUNG_DNG |
| m_DNGCaptureThread->requestExit(); |
| #endif |
| m_postPictureThread->requestExit(); |
| m_jpegCallbackThread->requestExit(); |
| |
| CLOGI("INFO(%s[%d]): wait m_prePictureThrad", __FUNCTION__, __LINE__); |
| m_prePictureThread->requestExitAndWait(); |
| CLOGI("INFO(%s[%d]): wait m_pictureThrad", __FUNCTION__, __LINE__); |
| m_pictureThread->requestExitAndWait(); |
| #ifdef SAMSUNG_LLS_DEBLUR |
| CLOGI("INFO(%s[%d]): wait m_LDCaptureThread", __FUNCTION__, __LINE__); |
| m_LDCaptureThread->requestExitAndWait(); |
| #endif |
| CLOGI("INFO(%s[%d]): wait m_postPictureGscThread", __FUNCTION__, __LINE__); |
| m_postPictureGscThread->requestExitAndWait(); |
| #ifdef SAMSUNG_DEBLUR |
| CLOGI("INFO(%s[%d]): wait m_detectDeblurCaptureThread", __FUNCTION__, __LINE__); |
| m_detectDeblurCaptureThread->requestExitAndWait(); |
| CLOGI("INFO(%s[%d]): wait m_deblurCaptureThread", __FUNCTION__, __LINE__); |
| m_deblurCaptureThread->requestExitAndWait(); |
| #endif |
| CLOGI("INFO(%s[%d]): wait m_ThumbnailCallbackThread", __FUNCTION__, __LINE__); |
| m_ThumbnailCallbackThread->requestExitAndWait(); |
| #ifdef SAMSUNG_DNG |
| CLOGI("INFO(%s[%d]): wait m_DNGCaptureThread", __FUNCTION__, __LINE__); |
| m_DNGCaptureThread->requestExitAndWait(); |
| #endif |
| CLOGI("INFO(%s[%d]): wait m_postPictureThrad", __FUNCTION__, __LINE__); |
| m_postPictureThread->requestExitAndWait(); |
| |
| m_exynosCameraParameters->setIsThumbnailCallbackOn(false); |
| |
| CLOGI("INFO(%s[%d]): wait m_jpegCallbackThrad", __FUNCTION__, __LINE__); |
| if (!callFromJpeg) |
| m_jpegCallbackThread->requestExitAndWait(); |
| |
| for (int threadNum = JPEG_SAVE_THREAD0; threadNum < JPEG_SAVE_THREAD_MAX_COUNT; threadNum++) { |
| CLOGI("INFO(%s[%d]): wait m_jpegSaveThrad%d", __FUNCTION__, __LINE__, threadNum); |
| m_jpegSaveThread[threadNum]->requestExitAndWait(); |
| } |
| |
| CLOGI("INFO(%s[%d]): All picture threads done", __FUNCTION__, __LINE__); |
| |
| if (m_exynosCameraParameters->isReprocessing() == true) { |
| enum pipeline pipe = (isOwnScc(getCameraId()) == true) ? PIPE_SCC_REPROCESSING : PIPE_ISP_REPROCESSING; |
| |
| m_reprocessingFrameFactory->stopThread(pipe); |
| } |
| |
| #ifdef SAMSUNG_MAGICSHOT |
| if (m_exynosCameraParameters->getShotMode() == SHOT_MODE_MAGIC) { |
| if(m_exynosCameraParameters->isReprocessing() == true) { |
| m_reprocessingFrameFactory->stopThread(PIPE_GSC_REPROCESSING2); |
| CLOGI("INFO(%s[%d]):rear gsc , pipe stop(%d)",__FUNCTION__, __LINE__, PIPE_GSC_REPROCESSING2); |
| } else { |
| enum pipeline pipe = PIPE_GSC_VIDEO; |
| |
| m_previewFrameFactory->stopThread(pipe); |
| CLOGI("INFO(%s[%d]):front gsc , pipe stop(%d)",__FUNCTION__, __LINE__, pipe); |
| } |
| } |
| #endif |
| |
| if(m_exynosCameraParameters->isReprocessing() == true) { |
| m_reprocessingFrameFactory->stopThread(PIPE_GSC_REPROCESSING3); |
| CLOGI("INFO(%s[%d]):rear gsc , pipe stop(%d)",__FUNCTION__, __LINE__, PIPE_GSC_REPROCESSING3); |
| } |
| |
| while (m_jpegCallbackQ->getSizeOfProcessQ() > 0) { |
| m_jpegCallbackQ->popProcessQ(&jpegCallbackBuf); |
| jpegCallbackBuffer = jpegCallbackBuf.buffer; |
| |
| CLOGD("DEBUG(%s[%d]):put remaining jpeg buffer(index: %d)", __FUNCTION__, __LINE__, jpegCallbackBuffer.index); |
| if (m_jpegBufferMgr->putBuffer(jpegCallbackBuffer.index, EXYNOS_CAMERA_BUFFER_POSITION_NONE) != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):putBuffer(%d) fail", __FUNCTION__, __LINE__, jpegCallbackBuffer.index); |
| } |
| |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| if (m_exynosCameraParameters->getSeriesShotMode() != SERIES_SHOT_MODE_ONE_SECOND_BURST) { |
| #endif |
| int seriesShotSaveLocation = m_exynosCameraParameters->getSeriesShotSaveLocation(); |
| char command[CAMERA_FILE_PATH_SIZE]; |
| memset(command, 0, sizeof(command)); |
| |
| #ifdef SAMSUNG_INF_BURST |
| snprintf(command, sizeof(command), "rm %s%s_%03d.jpg", m_burstSavePath, m_burstTime, jpegCallbackBuf.callbackNumber); |
| #else |
| snprintf(command, sizeof(command), "rm %sBurst%02d.jpg", m_burstSavePath, jpegCallbackBuf.callbackNumber); |
| #endif |
| |
| CLOGD("DEBUG(%s[%d]):run %s - start", __FUNCTION__, __LINE__, command); |
| system(command); |
| CLOGD("DEBUG(%s[%d]):run %s - end", __FUNCTION__, __LINE__, command); |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| } |
| #endif |
| } |
| |
| m_getBufferManager(PIPE_GSC_REPROCESSING3, &thumbnailBufferMgr, SRC_BUFFER_DIRECTION); |
| while (m_thumbnailCallbackQ->getSizeOfProcessQ() > 0) { |
| m_thumbnailCallbackQ->popProcessQ(&thumbnailCallbackBuffer); |
| |
| CLOGD("DEBUG(%s[%d]):put remaining thumbnailCallbackBuffer buffer(index: %d)", __FUNCTION__, __LINE__, postviewCallbackBuffer.index); |
| m_putBuffers(thumbnailBufferMgr, thumbnailCallbackBuffer.index); |
| } |
| |
| m_getBufferManager(PIPE_GSC_REPROCESSING3, &postviewBufferMgr, DST_BUFFER_DIRECTION); |
| while (m_postviewCallbackQ->getSizeOfProcessQ() > 0) { |
| m_postviewCallbackQ->popProcessQ(&postviewCallbackBuffer); |
| |
| CLOGD("DEBUG(%s[%d]):put remaining postview buffer(index: %d)", __FUNCTION__, __LINE__, postviewCallbackBuffer.index); |
| m_putBuffers(postviewBufferMgr, postviewCallbackBuffer.index); |
| } |
| |
| #ifdef SAMSUNG_DNG |
| ExynosCameraBuffer dngBuffer; |
| while (m_dngCaptureQ->getSizeOfProcessQ() > 0) { |
| m_dngCaptureQ->popProcessQ(&dngBuffer); |
| |
| CLOGD("DEBUG(%s[%d]):put remaining dngBuffer buffer(index: %d)", __FUNCTION__, __LINE__, dngBuffer.index); |
| m_putBuffers(m_fliteBufferMgr, dngBuffer.index); |
| } |
| #endif |
| |
| for (int threadNum = JPEG_SAVE_THREAD0; threadNum < JPEG_SAVE_THREAD_MAX_COUNT; threadNum++) { |
| while (m_jpegSaveQ[threadNum]->getSizeOfProcessQ() > 0) { |
| m_jpegSaveQ[threadNum]->popProcessQ(&jpegCallbackBuf); |
| jpegCallbackBuffer = jpegCallbackBuf.buffer; |
| |
| CLOGD("DEBUG(%s[%d]):put remaining SaveQ%d jpeg buffer(index: %d)", |
| __FUNCTION__, __LINE__, threadNum, jpegCallbackBuffer.index); |
| if (m_jpegBufferMgr->putBuffer(jpegCallbackBuffer.index, EXYNOS_CAMERA_BUFFER_POSITION_NONE) != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):putBuffer(%d) fail", __FUNCTION__, __LINE__, jpegCallbackBuffer.index); |
| } |
| |
| } |
| |
| m_burst[threadNum] = false; |
| } |
| |
| if (m_exynosCameraParameters->isReprocessing() == true) { |
| int ret = 0; |
| enum pipeline pipe = (isOwnScc(getCameraId()) == true) ? PIPE_SCC_REPROCESSING : PIPE_ISP_REPROCESSING; |
| CLOGD("DEBUG(%s[%d]): Wait thread exit Pipe(%d) ", __FUNCTION__, __LINE__, pipe); |
| ret = m_reprocessingFrameFactory->stopThreadAndWait(pipe); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):stopThread fail, pipe(%d) ret(%d)", __FUNCTION__, __LINE__, pipe, ret); |
| } |
| } |
| |
| if (m_exynosCameraParameters->isReprocessing() == true) { |
| int ret = 0; |
| enum pipeline pipes[] = {PIPE_GSC_REPROCESSING, PIPE_GSC_REPROCESSING2, PIPE_GSC_REPROCESSING3}; |
| for(uint32_t i = 0; i < sizeof(pipes) / sizeof(enum pipeline); i++) { |
| ret = m_reprocessingFrameFactory->stopThread(INDEX(pipes[i])); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):GSC stopThread fail, pipe(%d) ret(%d)", __FUNCTION__, __LINE__, pipes[i], ret); |
| } |
| ret = m_reprocessingFrameFactory->stopThreadAndWait(INDEX(pipes[i])); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): stopThreadAndWait fail, pipeId(%d) ret(%d)", __FUNCTION__, __LINE__, pipes[i], ret); |
| } |
| } |
| } |
| |
| CLOGD("DEBUG(%s[%d]): clear postProcessList", __FUNCTION__, __LINE__); |
| if (m_clearList(&m_postProcessList) < 0) { |
| CLOGE("ERR(%s):m_clearList fail", __FUNCTION__); |
| } |
| |
| #if 1 |
| CLOGD("DEBUG(%s[%d]): clear dstPostPictureGscQ", __FUNCTION__, __LINE__); |
| dstPostPictureGscQ->release(); |
| |
| CLOGD("DEBUG(%s[%d]): clear postPictureQ", __FUNCTION__, __LINE__); |
| m_postPictureQ->release(); |
| |
| CLOGD("DEBUG(%s[%d]): clear dstSccReprocessingQ", __FUNCTION__, __LINE__); |
| dstSccReprocessingQ->release(); |
| |
| CLOGD("DEBUG(%s[%d]): clear dstJpegReprocessingQ", __FUNCTION__, __LINE__); |
| dstJpegReprocessingQ->release(); |
| #else |
| ExynosCameraFrame *frame = NULL; |
| |
| CLOGD("DEBUG(%s[%d]): clear postPictureQ", __FUNCTION__, __LINE__); |
| while(m_postPictureQ->getSizeOfProcessQ()) { |
| m_postPictureQ->popProcessQ(&frame); |
| if (frame != NULL) { |
| delete frame; |
| frame = NULL; |
| } |
| } |
| |
| CLOGD("DEBUG(%s[%d]): clear dstSccReprocessingQ", __FUNCTION__, __LINE__); |
| while(dstSccReprocessingQ->getSizeOfProcessQ()) { |
| dstSccReprocessingQ->popProcessQ(&frame); |
| if (frame != NULL) { |
| delete frame; |
| frame = NULL; |
| } |
| } |
| #endif |
| |
| #ifdef SAMSUNG_DEBLUR |
| CLOGD("DEBUG(%s[%d]): clear m_deblurCaptureQ", __FUNCTION__, __LINE__); |
| m_deblurCaptureQ->release(); |
| CLOGD("DEBUG(%s[%d]): clear m_detectDeblurCaptureQ", __FUNCTION__, __LINE__); |
| m_detectDeblurCaptureQ->release(); |
| #endif |
| |
| #ifdef SAMSUNG_LLS_DEBLUR |
| CLOGD("DEBUG(%s[%d]): clear m_LDCaptureQ", __FUNCTION__, __LINE__); |
| m_LDCaptureQ->release(); |
| #endif |
| |
| if (needGSCForCapture(getCameraId()) == true) { |
| CLOGD("DEBUG(%s[%d]): reset postPictureGsc buffers", __FUNCTION__, __LINE__); |
| m_postPictureGscBufferMgr->resetBuffers(); |
| } |
| |
| CLOGD("DEBUG(%s[%d]): reset thumbnail gsc buffers", __FUNCTION__, __LINE__); |
| m_thumbnailGscBufferMgr->resetBuffers(); |
| |
| CLOGD("DEBUG(%s[%d]): reset buffer gsc buffers", __FUNCTION__, __LINE__); |
| m_gscBufferMgr->resetBuffers(); |
| CLOGD("DEBUG(%s[%d]): reset buffer jpeg buffers", __FUNCTION__, __LINE__); |
| m_jpegBufferMgr->resetBuffers(); |
| CLOGD("DEBUG(%s[%d]): reset buffer sccReprocessing buffers", __FUNCTION__, __LINE__); |
| m_sccReprocessingBufferMgr->resetBuffers(); |
| |
| #ifdef SAMSUNG_DNG |
| if (m_exynosCameraParameters->getDNGCaptureModeOn()) { |
| int waitCount = 100; |
| while (m_previewFrameFactory->getRunningFrameCount(PIPE_FLITE) != 0 && 0 < waitCount) { |
| CLOGD("DNG(%s[%d]): wait flite dqbuffer count(%d)", |
| __FUNCTION__, __LINE__, m_previewFrameFactory->getRunningFrameCount(PIPE_FLITE)); |
| usleep(30000); |
| waitCount--; |
| } |
| |
| if (m_exynosCameraParameters->getCheckMultiFrame()) { |
| CLOGE("[DNG](%s[%d]):PIPE_FLITE stop", __FUNCTION__, __LINE__); |
| m_exynosCameraParameters->setUseDNGCapture(false); |
| m_exynosCameraParameters->setCheckMultiFrame(false); |
| m_previewFrameFactory->stopThread(PIPE_FLITE); |
| m_previewFrameFactory->stopThreadAndWait(PIPE_FLITE); |
| } |
| |
| CLOGD("DNG(%s[%d]): reset m_fliteBuffer buffers", __FUNCTION__, __LINE__); |
| m_fliteBufferMgr->resetBuffers(); |
| } |
| #endif |
| |
| #ifdef BURST_CAPTURE |
| m_burstShutterLocation = BURST_SHUTTER_PREPICTURE; |
| #endif |
| } |
| |
| bool ExynosCamera::m_highResolutionCallbackThreadFunc(void) |
| { |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| CLOGI("INFO(%s[%d]):", __FUNCTION__, __LINE__); |
| |
| int ret = 0; |
| int loop = false; |
| int retryCountGSC = 4; |
| |
| ExynosCameraFrame *newFrame = NULL; |
| camera2_stream *shot_stream = NULL; |
| |
| ExynosCameraBuffer sccReprocessingBuffer; |
| ExynosCameraBuffer highResolutionCbBuffer; |
| |
| int cbPreviewW = 0, cbPreviewH = 0; |
| int previewFormat = 0; |
| ExynosRect srcRect, dstRect; |
| m_exynosCameraParameters->getPreviewSize(&cbPreviewW, &cbPreviewH); |
| previewFormat = m_exynosCameraParameters->getPreviewFormat(); |
| |
| int pipeId_scc = 0; |
| int pipeId_gsc = 0; |
| |
| unsigned int planeSize[EXYNOS_CAMERA_BUFFER_MAX_PLANES] = {0}; |
| unsigned int bytesPerLine[EXYNOS_CAMERA_BUFFER_MAX_PLANES] = {0}; |
| int planeCount = getYuvPlaneCount(previewFormat); |
| int minBufferCount = 1; |
| int maxBufferCount = 1; |
| int buffer_idx = getShotBufferIdex(); |
| |
| sccReprocessingBuffer.index = -2; |
| highResolutionCbBuffer.index = -2; |
| |
| pipeId_scc = (isOwnScc(getCameraId()) == true) ? PIPE_SCC_REPROCESSING : PIPE_ISP_REPROCESSING; |
| pipeId_gsc = PIPE_GSC_REPROCESSING; |
| |
| exynos_camera_buffer_type_t type = EXYNOS_CAMERA_BUFFER_ION_CACHED_TYPE; |
| buffer_manager_allocation_mode_t allocMode = BUFFER_MANAGER_ALLOCATION_ONDEMAND; |
| |
| if (m_exynosCameraParameters->getHighResolutionCallbackMode() == false && |
| m_highResolutionCallbackRunning == false) { |
| CLOGD("DEBUG(%s[%d]): High Resolution Callback Stop", __FUNCTION__, __LINE__); |
| goto CLEAN; |
| } |
| |
| ret = getYuvPlaneSize(previewFormat, planeSize, cbPreviewW, cbPreviewH); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): BAD value, format(%x), size(%dx%d)", |
| __FUNCTION__, __LINE__, previewFormat, cbPreviewW, cbPreviewH); |
| return ret; |
| } |
| |
| /* wait SCC */ |
| CLOGV("INFO(%s[%d]):wait SCC output", __FUNCTION__, __LINE__); |
| ret = m_highResolutionCallbackQ->waitAndPopProcessQ(&newFrame); |
| if (m_flagThreadStop == true) { |
| CLOGI("INFO(%s[%d]):m_flagThreadStop(%d)", __FUNCTION__, __LINE__, m_flagThreadStop); |
| goto CLEAN; |
| } |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| // TODO: doing exception handling |
| goto CLEAN; |
| } |
| if (newFrame == NULL) { |
| CLOGE("ERR(%s[%d]):newFrame is NULL", __FUNCTION__, __LINE__); |
| goto CLEAN; |
| } |
| |
| ret = newFrame->setEntityState(pipeId_scc, ENTITY_STATE_COMPLETE); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setEntityState(ENTITY_STATE_PROCESSING) fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId_scc, ret); |
| return ret; |
| } |
| CLOGV("INFO(%s[%d]):SCC output done", __FUNCTION__, __LINE__); |
| |
| if (m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) { |
| /* check dst buffer state for NDONE */ |
| sccReprocessingBuffer.index = -1; |
| |
| if (newFrame->getRequest(PIPE_ISPC_REPROCESSING) == true) { |
| /* get GSC src buffer */ |
| ret = newFrame->getDstBuffer(pipeId_scc, &sccReprocessingBuffer, |
| m_reprocessingFrameFactory->getNodeType(PIPE_ISPC_REPROCESSING)); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):getSrcBuffer fail, pipeId(%d), ret(%d) frame(%d)", |
| __FUNCTION__, __LINE__, pipeId_scc, ret, newFrame->getFrameCount()); |
| goto CLEAN; |
| } |
| } else { |
| CLOGE("ERR(%s[%d]):getRequest fail, pipeId(%d), ret(%d), frame(%d), dstBufPos(%d)", |
| __FUNCTION__, __LINE__, pipeId_scc, ret, newFrame->getFrameCount(), |
| m_reprocessingFrameFactory->getNodeType(PIPE_ISPC_REPROCESSING)); |
| goto CLEAN; |
| } |
| |
| if (sccReprocessingBuffer.index >= 0) { |
| entity_buffer_state_t bufferstate = ENTITY_BUFFER_STATE_NOREQ; |
| ret = newFrame->getDstBufferState(pipeId_scc, &bufferstate, |
| m_reprocessingFrameFactory->getNodeType(PIPE_ISPC_REPROCESSING)); |
| if (ret != NO_ERROR || bufferstate == ENTITY_BUFFER_STATE_ERROR) { |
| CLOGE("ERR(%s[%d]):getDstBufferState fail, pipeId(%d), ret(%d) bufferState(%d) frame(%d)", |
| __FUNCTION__, __LINE__, pipeId_scc, ret, bufferstate, newFrame->getFrameCount()); |
| goto CLEAN; |
| } |
| } |
| |
| shot_stream = (struct camera2_stream *)(sccReprocessingBuffer.addr[buffer_idx]); |
| if (shot_stream == NULL) { |
| CLOGE("ERR(%s[%d]):shot_stream is NULL. buffer(%d)", |
| __FUNCTION__, __LINE__, sccReprocessingBuffer.index); |
| goto CLEAN; |
| } |
| |
| /* alloc GSC buffer */ |
| if (m_highResolutionCallbackBufferMgr->isAllocated() == false) { |
| ret = m_allocBuffers(m_highResolutionCallbackBufferMgr, planeCount, planeSize, |
| bytesPerLine, minBufferCount, maxBufferCount, type, allocMode, false, false); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_highResolutionCallbackBufferMgr m_allocBuffers(minBufferCount=%d, maxBufferCount=%d) fail", |
| __FUNCTION__, __LINE__, minBufferCount, maxBufferCount); |
| return ret; |
| } |
| } |
| |
| /* get GSC dst buffer */ |
| int bufIndex = -2; |
| m_highResolutionCallbackBufferMgr->getBuffer(&bufIndex, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL, &highResolutionCbBuffer); |
| |
| /* get preview callback heap */ |
| camera_memory_t *previewCallbackHeap = NULL; |
| previewCallbackHeap = m_getMemoryCb(highResolutionCbBuffer.fd[0], highResolutionCbBuffer.size[0], 1, m_callbackCookie); |
| if (!previewCallbackHeap || previewCallbackHeap->data == MAP_FAILED) { |
| CLOGE("ERR(%s[%d]):m_getMemoryCb(%d) fail", __FUNCTION__, __LINE__, highResolutionCbBuffer.size[0]); |
| goto CLEAN; |
| } |
| |
| ret = m_setCallbackBufferInfo(&highResolutionCbBuffer, (char *)previewCallbackHeap->data); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): setCallbackBufferInfo fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto CLEAN; |
| } |
| |
| /* set src/dst rect */ |
| srcRect.x = shot_stream->output_crop_region[0]; |
| srcRect.y = shot_stream->output_crop_region[1]; |
| srcRect.w = shot_stream->output_crop_region[2]; |
| srcRect.h = shot_stream->output_crop_region[3]; |
| |
| ret = m_calcHighResolutionPreviewGSCRect(&srcRect, &dstRect); |
| ret = newFrame->setSrcRect(pipeId_gsc, &srcRect); |
| ret = newFrame->setDstRect(pipeId_gsc, &dstRect); |
| |
| CLOGV("DEBUG(%s[%d]):srcRect x : %d, y : %d, w : %d, h : %d", __FUNCTION__, __LINE__, srcRect.x, srcRect.y, srcRect.w, srcRect.h); |
| CLOGV("DEBUG(%s[%d]):dstRect x : %d, y : %d, w : %d, h : %d", __FUNCTION__, __LINE__, dstRect.x, dstRect.y, dstRect.w, dstRect.h); |
| |
| ret = m_setupEntity(pipeId_gsc, newFrame, &sccReprocessingBuffer, &highResolutionCbBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId_gsc, ret); |
| goto CLEAN; |
| } |
| |
| /* push frame to GSC pipe */ |
| m_pictureFrameFactory->setOutputFrameQToPipe(dstGscReprocessingQ, pipeId_gsc); |
| m_pictureFrameFactory->pushFrameToPipe(&newFrame, pipeId_gsc); |
| |
| /* wait GSC for high resolution preview callback */ |
| CLOGI("INFO(%s[%d]):wait GSC output", __FUNCTION__, __LINE__); |
| newFrame = NULL; |
| while (retryCountGSC > 0) { |
| ret = dstGscReprocessingQ->waitAndPopProcessQ(&newFrame); |
| if (ret == TIMED_OUT) { |
| CLOGW("WRN(%s)(%d):wait and pop timeout, ret(%d)", __FUNCTION__, __LINE__, ret); |
| m_pictureFrameFactory->startThread(pipeId_gsc); |
| } else if (ret < 0) { |
| CLOGE("ERR(%s)(%d):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| /* TODO: doing exception handling */ |
| goto CLEAN; |
| } else { |
| break; |
| } |
| retryCountGSC--; |
| } |
| |
| if (newFrame == NULL) { |
| CLOGE("ERR(%s):newFrame is NULL", __FUNCTION__); |
| goto CLEAN; |
| } |
| CLOGI("INFO(%s[%d]):GSC output done", __FUNCTION__, __LINE__); |
| |
| /* put SCC buffer */ |
| ret = newFrame->getDstBuffer(pipeId_scc, &sccReprocessingBuffer, |
| m_reprocessingFrameFactory->getNodeType(PIPE_ISPC_REPROCESSING)); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId_scc, ret); |
| goto CLEAN; |
| } |
| ret = m_putBuffers(m_sccReprocessingBufferMgr, sccReprocessingBuffer.index); |
| |
| CLOGV("DEBUG(%s[%d]):high resolution preview callback", __FUNCTION__, __LINE__); |
| if (m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) { |
| setBit(&m_callbackState, CALLBACK_STATE_PREVIEW_FRAME, false); |
| m_dataCb(CAMERA_MSG_PREVIEW_FRAME, previewCallbackHeap, 0, NULL, m_callbackCookie); |
| clearBit(&m_callbackState, CALLBACK_STATE_PREVIEW_FRAME, false); |
| } |
| |
| previewCallbackHeap->release(previewCallbackHeap); |
| |
| highResolutionCbBuffer.index = -2; |
| ret = newFrame->getDstBuffer(pipeId_gsc, &highResolutionCbBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId_gsc, ret); |
| } |
| |
| /* put high resolution callback buffer */ |
| if (highResolutionCbBuffer.index >=0) |
| m_putBuffers(m_highResolutionCallbackBufferMgr, highResolutionCbBuffer.index); |
| |
| if (newFrame != NULL) { |
| newFrame->frameUnlock(); |
| ret = m_removeFrameFromList(&m_postProcessList, newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):remove frame from processList fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| |
| CLOGD("DEBUG(%s[%d]): Reprocessing frame delete(%d)", __FUNCTION__, __LINE__, newFrame->getFrameCount()); |
| newFrame->decRef(); |
| m_frameMgr->deleteFrame(newFrame); |
| newFrame = NULL; |
| } |
| } else { |
| CLOGD("DEBUG(%s[%d]): Preview callback message disabled, skip callback", __FUNCTION__, __LINE__); |
| /* put SCC buffer */ |
| ret = newFrame->getDstBuffer(pipeId_scc, &sccReprocessingBuffer, |
| m_reprocessingFrameFactory->getNodeType(PIPE_ISPC_REPROCESSING)); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId_scc, ret); |
| goto CLEAN; |
| } |
| ret = m_putBuffers(m_sccReprocessingBufferMgr, sccReprocessingBuffer.index); |
| } |
| |
| if(m_flagThreadStop != true) { |
| if (m_highResolutionCallbackQ->getSizeOfProcessQ() > 0 || |
| m_exynosCameraParameters->getHighResolutionCallbackMode() == true) { |
| CLOGD("DEBUG(%s[%d]):highResolutionCallbackQ size(%d), highResolutionCallbackMode(%s), start again", |
| __FUNCTION__, __LINE__, |
| m_highResolutionCallbackQ->getSizeOfProcessQ(), |
| (m_exynosCameraParameters->getHighResolutionCallbackMode() == true)? "TRUE" : "FALSE"); |
| loop = true; |
| } |
| } |
| |
| CLOGI("INFO(%s[%d]):high resolution callback thread complete, loop(%d)", __FUNCTION__, __LINE__, loop); |
| |
| /* one shot */ |
| return loop; |
| |
| CLEAN: |
| if (newFrame != NULL) { |
| sccReprocessingBuffer.index = -2; |
| ret = newFrame->getDstBuffer(pipeId_scc, &sccReprocessingBuffer, |
| m_reprocessingFrameFactory->getNodeType(PIPE_ISPC_REPROCESSING)); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId_scc, ret); |
| } |
| if (sccReprocessingBuffer.index >= 0) |
| m_putBuffers(m_sccReprocessingBufferMgr, sccReprocessingBuffer.index); |
| |
| highResolutionCbBuffer.index = -2; |
| ret = newFrame->getDstBuffer(pipeId_gsc, &highResolutionCbBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId_gsc, ret); |
| } |
| |
| if (highResolutionCbBuffer.index >= 0) |
| m_putBuffers(m_highResolutionCallbackBufferMgr, highResolutionCbBuffer.index); |
| } |
| |
| if (newFrame != NULL) { |
| newFrame->printEntity(); |
| |
| newFrame->frameUnlock(); |
| ret = m_removeFrameFromList(&m_postProcessList, newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):remove frame from processList fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| |
| newFrame->decRef(); |
| m_frameMgr->deleteFrame(newFrame); |
| newFrame = NULL; |
| } |
| |
| if(m_flagThreadStop != true) { |
| if (m_highResolutionCallbackQ->getSizeOfProcessQ() > 0 || |
| m_exynosCameraParameters->getHighResolutionCallbackMode() == true) { |
| CLOGD("DEBUG(%s[%d]):highResolutionCallbackQ size(%d), highResolutionCallbackMode(%s), start again", |
| __FUNCTION__, __LINE__, |
| m_highResolutionCallbackQ->getSizeOfProcessQ(), |
| (m_exynosCameraParameters->getHighResolutionCallbackMode() == true)? "TRUE" : "FALSE"); |
| loop = true; |
| } |
| } |
| |
| CLOGI("INFO(%s[%d]):high resolution callback thread fail, loop(%d)", __FUNCTION__, __LINE__, loop); |
| |
| /* one shot */ |
| return loop; |
| } |
| |
| status_t ExynosCamera::m_doPrviewToRecordingFunc( |
| int32_t pipeId, |
| ExynosCameraBuffer previewBuf, |
| ExynosCameraBuffer recordingBuf, |
| nsecs_t timeStamp) |
| { |
| #ifdef DEBUG |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| #endif |
| |
| CLOGV("DEBUG(%s[%d]):--IN-- (previewBuf.index=%d, recordingBuf.index=%d)", |
| __FUNCTION__, __LINE__, previewBuf.index, recordingBuf.index); |
| |
| status_t ret = NO_ERROR; |
| ExynosRect srcRect, dstRect; |
| ExynosCameraFrame *newFrame = NULL; |
| struct camera2_node_output node; |
| |
| newFrame = m_previewFrameFactory->createNewFrameVideoOnly(); |
| if (newFrame == NULL) { |
| CLOGE("ERR(%s):newFrame is NULL", __FUNCTION__); |
| return UNKNOWN_ERROR; |
| } |
| |
| /* TODO: HACK: Will be removed, this is driver's job */ |
| m_convertingStreamToShotExt(&previewBuf, &node); |
| setMetaDmSensorTimeStamp((struct camera2_shot_ext*)previewBuf.addr[previewBuf.planeCount-1], timeStamp); |
| |
| /* csc and scaling */ |
| ret = m_calcRecordingGSCRect(&srcRect, &dstRect); |
| ret = newFrame->setSrcRect(pipeId, srcRect); |
| ret = newFrame->setDstRect(pipeId, dstRect); |
| |
| ret = m_setupEntity(pipeId, newFrame, &previewBuf, &recordingBuf); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId, ret); |
| ret = INVALID_OPERATION; |
| if (newFrame != NULL) { |
| newFrame->decRef(); |
| m_frameMgr->deleteFrame(newFrame); |
| newFrame = NULL; |
| } |
| goto func_exit; |
| } |
| m_recordingListLock.lock(); |
| m_recordingProcessList.push_back(newFrame); |
| m_recordingListLock.unlock(); |
| m_previewFrameFactory->setOutputFrameQToPipe(m_recordingQ, pipeId); |
| |
| m_recordingStopLock.lock(); |
| if (m_getRecordingEnabled() == false) { |
| m_recordingStopLock.unlock(); |
| CLOGD("DEBUG(%s[%d]): m_getRecordingEnabled is false, skip frame(%d) previewBuf(%d) recordingBuf(%d)", |
| __FUNCTION__, __LINE__, newFrame->getFrameCount(), previewBuf.index, recordingBuf.index); |
| if (newFrame != NULL) { |
| newFrame->decRef(); |
| m_frameMgr->deleteFrame(newFrame); |
| newFrame = NULL; |
| } |
| |
| if (recordingBuf.index >= 0){ |
| m_putBuffers(m_recordingBufferMgr, recordingBuf.index); |
| } |
| goto func_exit; |
| } |
| m_previewFrameFactory->pushFrameToPipe(&newFrame, pipeId); |
| m_recordingStopLock.unlock(); |
| |
| func_exit: |
| |
| CLOGV("DEBUG(%s[%d]):--OUT--", __FUNCTION__, __LINE__); |
| return ret; |
| |
| } |
| |
| bool ExynosCamera::m_recordingThreadFunc(void) |
| { |
| #ifdef DEBUG |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| #endif |
| |
| int ret = 0; |
| int pipeId = PIPE_GSC_VIDEO; |
| nsecs_t timeStamp = 0; |
| |
| ExynosCameraBuffer buffer; |
| ExynosCameraFrame *frame = NULL; |
| |
| CLOGV("INFO(%s[%d]):wait gsc done output", __FUNCTION__, __LINE__); |
| ret = m_recordingQ->waitAndPopProcessQ(&frame); |
| if (m_getRecordingEnabled() == false) { |
| CLOGI("INFO(%s[%d]):recording stopped", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| if (ret < 0) { |
| if (ret == TIMED_OUT) { |
| CLOGW("WARN(%s):wait timeout", __FUNCTION__); |
| } else { |
| CLOGE("ERR(%s):wait and pop fail, ret(%d)", __FUNCTION__, ret); |
| /* TODO: doing exception handling */ |
| } |
| goto func_exit; |
| } |
| |
| if (frame == NULL) { |
| CLOGE("ERR(%s[%d]):frame is NULL", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| CLOGV("INFO(%s[%d]):gsc done for recording callback", __FUNCTION__, __LINE__); |
| |
| ret = frame->getSrcBuffer(pipeId, &buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| /* TODO: doing exception handling */ |
| goto func_exit; |
| } |
| |
| timeStamp = getMetaDmSensorTimeStamp((struct camera2_shot_ext*)buffer.addr[buffer.planeCount-1]); |
| |
| ret = frame->getDstBuffer(pipeId, &buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| /* TODO: doing exception handling */ |
| goto func_exit; |
| } |
| |
| if (buffer.index < 0 || buffer.index >= (int)m_recordingBufferCount) { |
| CLOGE("ERR(%s[%d]):Out of Index! (Max: %d, Index: %d)", __FUNCTION__, __LINE__, m_recordingBufferCount, buffer.index); |
| goto func_exit; |
| } |
| |
| if (m_recordingStartTimeStamp == 0) { |
| m_recordingStartTimeStamp = timeStamp; |
| CLOGI("INFO(%s[%d]):m_recordingStartTimeStamp=%lld", |
| __FUNCTION__, __LINE__, (long long)m_recordingStartTimeStamp); |
| } |
| |
| if ((0L < timeStamp) |
| && (m_lastRecordingTimeStamp < timeStamp) |
| && (m_recordingStartTimeStamp <= timeStamp)) { |
| if (m_getRecordingEnabled() == true |
| && m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_VIDEO_FRAME)) { |
| #ifdef CHECK_MONOTONIC_TIMESTAMP |
| CLOGD("DEBUG(%s[%d]):m_dataCbTimestamp::recordingFrameIndex=%d, recordingTimeStamp=%lld", |
| __FUNCTION__, __LINE__, buffer.index, timeStamp); |
| #endif |
| #ifdef DEBUG |
| CLOGD("DEBUG(%s[%d]): - lastTimeStamp(%lld), systemTime(%lld), recordingStart(%lld)", |
| __FUNCTION__, __LINE__, |
| m_lastRecordingTimeStamp, |
| systemTime(SYSTEM_TIME_MONOTONIC), |
| m_recordingStartTimeStamp); |
| #endif |
| struct VideoNativeHandleMetadata *recordAddrs = NULL; |
| |
| recordAddrs = (struct VideoNativeHandleMetadata *)m_recordingCallbackHeap->data; |
| recordAddrs[buffer.index].eType = kMetadataBufferTypeNativeHandleSource; |
| |
| native_handle* handle = native_handle_create(2, 1); |
| handle->data[0] = (int32_t) buffer.fd[0]; |
| handle->data[1] = (int32_t) buffer.fd[1]; |
| handle->data[2] = (int32_t) buffer.index; |
| |
| recordAddrs[buffer.index].pHandle = handle; |
| |
| m_recordingBufAvailable[buffer.index] = false; |
| |
| m_lastRecordingTimeStamp = timeStamp; |
| |
| #ifdef SAMSUNG_HLV |
| if (m_HLV) { |
| /* Ignore the ERROR .. HLV solution is smart */ |
| m_ProgramAndProcessHLV(&buffer); |
| } |
| #endif |
| |
| m_dataCbTimestamp( |
| timeStamp, |
| CAMERA_MSG_VIDEO_FRAME, |
| m_recordingCallbackHeap, |
| buffer.index, |
| m_callbackCookie); |
| } |
| } else { |
| CLOGW("WARN(%s[%d]):recordingFrameIndex=%d, timeStamp(%lld) invalid -" |
| " lastTimeStamp(%lld), systemTime(%lld), recordingStart(%lld)", |
| __FUNCTION__, __LINE__, buffer.index, (long long)timeStamp, |
| (long long)m_lastRecordingTimeStamp, |
| (long long)systemTime(SYSTEM_TIME_MONOTONIC), |
| (long long)m_recordingStartTimeStamp); |
| m_releaseRecordingBuffer(buffer.index); |
| } |
| |
| func_exit: |
| |
| m_recordingListLock.lock(); |
| if (frame != NULL) { |
| ret = m_removeFrameFromList(&m_recordingProcessList, frame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):remove frame from processList fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| frame->decRef(); |
| m_frameMgr->deleteFrame(frame);; |
| frame = NULL; |
| } |
| m_recordingListLock.unlock(); |
| |
| return m_recordingEnabled; |
| } |
| |
| status_t ExynosCamera::m_releaseRecordingBuffer(int bufIndex) |
| { |
| status_t ret = NO_ERROR; |
| |
| if (bufIndex < 0 || bufIndex >= (int)m_recordingBufferCount) { |
| CLOGE("ERR(%s):Out of Index! (Max: %d, Index: %d)", __FUNCTION__, m_recordingBufferCount, bufIndex); |
| ret = INVALID_OPERATION; |
| goto func_exit; |
| } |
| |
| ret = m_putBuffers(m_recordingBufferMgr, bufIndex); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):put Buffer fail", __FUNCTION__, __LINE__); |
| } |
| |
| func_exit: |
| |
| return ret; |
| } |
| |
| status_t ExynosCamera::m_calcPreviewGSCRect(ExynosRect *srcRect, ExynosRect *dstRect) |
| { |
| return m_exynosCameraParameters->calcPreviewGSCRect(srcRect, dstRect); |
| } |
| |
| status_t ExynosCamera::m_calcHighResolutionPreviewGSCRect(ExynosRect *srcRect, ExynosRect *dstRect) |
| { |
| return m_exynosCameraParameters->calcHighResolutionPreviewGSCRect(srcRect, dstRect); |
| } |
| |
| status_t ExynosCamera::m_calcRecordingGSCRect(ExynosRect *srcRect, ExynosRect *dstRect) |
| { |
| return m_exynosCameraParameters->calcRecordingGSCRect(srcRect, dstRect); |
| } |
| |
| status_t ExynosCamera::m_calcPictureRect(ExynosRect *srcRect, ExynosRect *dstRect) |
| { |
| return m_exynosCameraParameters->calcPictureRect(srcRect, dstRect); |
| } |
| |
| status_t ExynosCamera::m_calcPictureRect(int originW, int originH, ExynosRect *srcRect, ExynosRect *dstRect) |
| { |
| return m_exynosCameraParameters->calcPictureRect(originW, originH, srcRect, dstRect); |
| } |
| |
| status_t ExynosCamera::m_searchFrameFromList(List<ExynosCameraFrame *> *list, uint32_t frameCount, ExynosCameraFrame **frame) |
| { |
| Mutex::Autolock lock(m_searchframeLock); |
| int ret = 0; |
| ExynosCameraFrame *curFrame = NULL; |
| List<ExynosCameraFrame *>::iterator r; |
| |
| if (list->empty()) { |
| CLOGD("DEBUG(%s[%d]):list is empty", __FUNCTION__, __LINE__); |
| return NO_ERROR; |
| } |
| |
| r = list->begin()++; |
| |
| do { |
| curFrame = *r; |
| if (curFrame == NULL) { |
| CLOGE("ERR(%s):curFrame is empty", __FUNCTION__); |
| return INVALID_OPERATION; |
| } |
| |
| if (frameCount == curFrame->getFrameCount()) { |
| CLOGV("DEBUG(%s):frame count match: expected(%d)", __FUNCTION__, frameCount); |
| *frame = curFrame; |
| return NO_ERROR; |
| } |
| r++; |
| } while (r != list->end()); |
| |
| CLOGV("DEBUG(%s[%d]):Cannot find match frame, frameCount(%d)", __FUNCTION__, __LINE__, frameCount); |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_removeFrameFromList(List<ExynosCameraFrame *> *list, ExynosCameraFrame *frame) |
| { |
| Mutex::Autolock lock(m_searchframeLock); |
| int ret = 0; |
| ExynosCameraFrame *curFrame = NULL; |
| int frameCount = 0; |
| int curFrameCount = 0; |
| List<ExynosCameraFrame *>::iterator r; |
| |
| if (frame == NULL) { |
| CLOGE("ERR(%s):frame is NULL", __FUNCTION__); |
| return BAD_VALUE; |
| } |
| |
| if (list->empty()) { |
| CLOGD("DEBUG(%s):list is empty", __FUNCTION__); |
| return NO_ERROR; |
| } |
| |
| frameCount = frame->getFrameCount(); |
| r = list->begin()++; |
| |
| do { |
| curFrame = *r; |
| if (curFrame == NULL) { |
| CLOGE("ERR(%s):curFrame is empty", __FUNCTION__); |
| return INVALID_OPERATION; |
| } |
| |
| curFrameCount = curFrame->getFrameCount(); |
| if (frameCount == curFrameCount) { |
| CLOGV("DEBUG(%s):frame count match: expected(%d), current(%d)", __FUNCTION__, frameCount, curFrameCount); |
| list->erase(r); |
| return NO_ERROR; |
| } |
| CLOGW("WARN(%s):frame count mismatch: expected(%d), current(%d)", __FUNCTION__, frameCount, curFrameCount); |
| /* removed message */ |
| /* curFrame->printEntity(); */ |
| r++; |
| } while (r != list->end()); |
| |
| CLOGE("ERR(%s):Cannot find match frame!!!", __FUNCTION__); |
| |
| return INVALID_OPERATION; |
| } |
| |
| status_t ExynosCamera::m_deleteFrame(ExynosCameraFrame **frame) |
| { |
| status_t ret = NO_ERROR; |
| |
| /* put lock using this frame */ |
| Mutex::Autolock lock(m_searchframeLock); |
| |
| if (*frame == NULL) { |
| CLOGE("ERR(%s[%d]):frame == NULL. so, fail", __FUNCTION__, __LINE__); |
| return BAD_VALUE; |
| } |
| |
| if ((*frame)->getFrameLockState() == false) { |
| if ((*frame)->isComplete() == true) { |
| CLOGD("DEBUG(%s[%d]): Reprocessing frame delete(%d)", __FUNCTION__, __LINE__, (*frame)->getFrameCount()); |
| |
| (*frame)->decRef(); |
| m_frameMgr->deleteFrame(*frame); |
| } |
| } |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_clearList(List<ExynosCameraFrame *> *list) |
| { |
| Mutex::Autolock lock(m_searchframeLock); |
| int ret = 0; |
| ExynosCameraFrame *curFrame = NULL; |
| List<ExynosCameraFrame *>::iterator r; |
| |
| CLOGD("DEBUG(%s):remaining frame(%d), we remove them all", __FUNCTION__, (int)list->size()); |
| |
| while (!list->empty()) { |
| r = list->begin()++; |
| curFrame = *r; |
| if (curFrame != NULL) { |
| CLOGV("DEBUG(%s):remove frame count %d", __FUNCTION__, curFrame->getFrameCount() ); |
| curFrame->decRef(); |
| m_frameMgr->deleteFrame(curFrame); |
| curFrame = NULL; |
| } |
| list->erase(r); |
| } |
| CLOGD("DEBUG(%s):EXIT ", __FUNCTION__); |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_clearList(frame_queue_t *queue) |
| { |
| Mutex::Autolock lock(m_searchframeLock); |
| int ret = 0; |
| ExynosCameraFrame *curFrame = NULL; |
| |
| CLOGD("DEBUG(%s):remaining frame(%d), we remove them all", __FUNCTION__, queue->getSizeOfProcessQ()); |
| |
| while (0 < queue->getSizeOfProcessQ()) { |
| queue->popProcessQ(&curFrame); |
| if (curFrame != NULL) { |
| CLOGV("DEBUG(%s):remove frame count %d", __FUNCTION__, curFrame->getFrameCount() ); |
| curFrame->decRef(); |
| m_frameMgr->deleteFrame(curFrame); |
| curFrame = NULL; |
| } |
| } |
| CLOGD("DEBUG(%s):EXIT ", __FUNCTION__); |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_clearFrameQ(frame_queue_t *frameQ, uint32_t pipeId, uint32_t direction) { |
| ExynosCameraFrame *newFrame = NULL; |
| ExynosCameraFrameEntity *entity = NULL; |
| ExynosCameraBuffer deleteSccBuffer; |
| ExynosCameraBufferManager *bufferMgr = NULL; |
| int ret = NO_ERROR; |
| |
| if (frameQ == NULL) { |
| CLOGE("ERR(%s[%d]):frameQ is NULL.", __FUNCTION__, __LINE__); |
| return INVALID_OPERATION; |
| } |
| |
| CLOGI("INFO(%s[%d]): IN... frameQSize(%d)", __FUNCTION__, __LINE__, frameQ->getSizeOfProcessQ()); |
| |
| while (0 < frameQ->getSizeOfProcessQ()) { |
| ret = frameQ->popProcessQ(&newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| continue; |
| } |
| |
| if (newFrame == NULL) { |
| CLOGE("ERR(%s[%d]):newFrame is NULL", __FUNCTION__, __LINE__); |
| ret = INVALID_OPERATION; |
| continue; |
| } |
| |
| if (direction == SRC_BUFFER_DIRECTION) { |
| ret = newFrame->getSrcBuffer(pipeId, &deleteSccBuffer); |
| } else { |
| if(m_previewFrameFactory == NULL) { |
| return INVALID_OPERATION; |
| } |
| ret = newFrame->getDstBuffer(pipeId, &deleteSccBuffer, m_previewFrameFactory->getNodeType(pipeId)); |
| } |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getSrcBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId, ret); |
| continue; |
| } |
| |
| ret = m_getBufferManager(pipeId, &bufferMgr, direction); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):getBufferManager(SRC) fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId, ret); |
| |
| /* put SCC buffer */ |
| CLOGD("DEBUG(%s)(%d):m_putBuffer by clearjpegthread(dstSccRe), index(%d)", __FUNCTION__, __LINE__, deleteSccBuffer.index); |
| ret = m_putBuffers(bufferMgr, deleteSccBuffer.index); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):bufferMgr->putBuffers() fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId, ret); |
| } |
| |
| return ret; |
| } |
| |
| status_t ExynosCamera::m_printFrameList(List<ExynosCameraFrame *> *list) |
| { |
| int ret = 0; |
| ExynosCameraFrame *curFrame = NULL; |
| List<ExynosCameraFrame *>::iterator r; |
| |
| CLOGD("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); |
| CLOGD("\t remaining frame count(%d)", (int)list->size()); |
| |
| r = list->begin()++; |
| |
| do { |
| curFrame = *r; |
| if (curFrame != NULL) { |
| CLOGI("\t hal frame count %d", curFrame->getFrameCount() ); |
| curFrame->printEntity(); |
| } |
| |
| r++; |
| } while (r != list->end()); |
| CLOGD("----------------------------------------------------------------------------"); |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_createIonAllocator(ExynosCameraIonAllocator **allocator) |
| { |
| status_t ret = NO_ERROR; |
| int retry = 0; |
| do { |
| retry++; |
| CLOGI("INFO(%s[%d]):try(%d) to create IonAllocator", __FUNCTION__, __LINE__, retry); |
| *allocator = new ExynosCameraIonAllocator(); |
| ret = (*allocator)->init(false); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):create IonAllocator fail (retryCount=%d)", __FUNCTION__, __LINE__, retry); |
| else { |
| CLOGD("DEBUG(%s[%d]):m_createIonAllocator success (allocator=%p)", __FUNCTION__, __LINE__, *allocator); |
| break; |
| } |
| } while (ret < 0 && retry < 3); |
| |
| if (ret < 0 && retry >=3) { |
| CLOGE("ERR(%s[%d]):create IonAllocator fail (retryCount=%d)", __FUNCTION__, __LINE__, retry); |
| ret = INVALID_OPERATION; |
| } |
| |
| return ret; |
| } |
| |
| status_t ExynosCamera::m_createInternalBufferManager(ExynosCameraBufferManager **bufferManager, const char *name) |
| { |
| return m_createBufferManager(bufferManager, name, BUFFER_MANAGER_ION_TYPE); |
| } |
| |
| status_t ExynosCamera::m_createBufferManager( |
| ExynosCameraBufferManager **bufferManager, |
| const char *name, |
| buffer_manager_type type) |
| { |
| status_t ret = NO_ERROR; |
| |
| if (m_ionAllocator == NULL) { |
| ret = m_createIonAllocator(&m_ionAllocator); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):m_createIonAllocator fail", __FUNCTION__, __LINE__); |
| else |
| CLOGD("DEBUG(%s[%d]):m_createIonAllocator success", __FUNCTION__, __LINE__); |
| } |
| |
| *bufferManager = ExynosCameraBufferManager::createBufferManager(type); |
| (*bufferManager)->create(name, m_cameraId, m_ionAllocator); |
| |
| CLOGD("DEBUG(%s):BufferManager(%s) created", __FUNCTION__, name); |
| |
| return ret; |
| } |
| |
| bool ExynosCamera::m_releasebuffersForRealloc() |
| { |
| status_t ret = NO_ERROR; |
| /* skip to free and reallocate buffers : flite / 3aa / isp / ispReprocessing */ |
| CLOGD("DEBUG(%s[%d]):m_setBuffers free all buffers", __FUNCTION__, __LINE__); |
| if (m_bayerBufferMgr != NULL) { |
| m_bayerBufferMgr->deinit(); |
| } |
| #ifdef SAMSUNG_DNG |
| if (m_fliteBufferMgr != NULL) { |
| m_fliteBufferMgr->deinit(); |
| } |
| #endif |
| if (m_3aaBufferMgr != NULL) { |
| m_3aaBufferMgr->deinit(); |
| } |
| if (m_ispBufferMgr != NULL) { |
| m_ispBufferMgr->deinit(); |
| } |
| if (m_hwDisBufferMgr != NULL) { |
| m_hwDisBufferMgr->deinit(); |
| } |
| |
| /* realloc callback buffers */ |
| if (m_scpBufferMgr != NULL) { |
| m_scpBufferMgr->deinit(); |
| m_scpBufferMgr->setBufferCount(0); |
| } |
| |
| if (m_sccBufferMgr != NULL) { |
| m_sccBufferMgr->deinit(); |
| } |
| |
| if (m_postPictureGscBufferMgr != NULL) { |
| m_postPictureGscBufferMgr->deinit(); |
| } |
| |
| if (m_thumbnailGscBufferMgr != NULL) { |
| m_thumbnailGscBufferMgr->deinit(); |
| } |
| |
| #ifdef SAMSUNG_LBP |
| if (m_lbpBufferMgr != NULL) { |
| m_lbpBufferMgr->deinit(); |
| } |
| #endif |
| |
| if (m_previewCallbackBufferMgr != NULL) { |
| m_previewCallbackBufferMgr->deinit(); |
| } |
| if (m_highResolutionCallbackBufferMgr != NULL) { |
| m_highResolutionCallbackBufferMgr->deinit(); |
| } |
| |
| m_exynosCameraParameters->setReallocBuffer(false); |
| |
| if (m_exynosCameraParameters->getRestartPreview() == true) { |
| ret = setPreviewWindow(m_previewWindow); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setPreviewWindow fail", __FUNCTION__, __LINE__); |
| return INVALID_OPERATION; |
| } |
| } |
| |
| return true; |
| } |
| |
| |
| status_t ExynosCamera::m_setBuffers(void) |
| { |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| |
| CLOGI("INFO(%s[%d]):alloc buffer - camera ID: %d", |
| __FUNCTION__, __LINE__, m_cameraId); |
| int ret = 0; |
| unsigned int bytesPerLine[EXYNOS_CAMERA_BUFFER_MAX_PLANES] = {0}; |
| unsigned int planeSize[EXYNOS_CAMERA_BUFFER_MAX_PLANES] = {0}; |
| int hwPreviewW, hwPreviewH; |
| int hwPictureW, hwPictureH; |
| |
| int ispBufferW, ispBufferH; |
| int previewMaxW, previewMaxH; |
| int pictureMaxW, pictureMaxH; |
| int sensorMaxW, sensorMaxH; |
| ExynosRect bdsRect; |
| |
| int planeCount = 1; |
| int maxBufferCount = 1; |
| exynos_camera_buffer_type_t type = EXYNOS_CAMERA_BUFFER_ION_NONCACHED_TYPE; |
| buffer_manager_allocation_mode_t allocMode = BUFFER_MANAGER_ALLOCATION_ATONCE; |
| |
| if( m_exynosCameraParameters->getReallocBuffer() ) { |
| /* skip to free and reallocate buffers : flite / 3aa / isp / ispReprocessing */ |
| m_releasebuffersForRealloc(); |
| } |
| |
| m_exynosCameraParameters->getHwPreviewSize(&hwPreviewW, &hwPreviewH); |
| CLOGI("(%s):HW Preview width x height = %dx%d", __FUNCTION__, hwPreviewW, hwPreviewH); |
| m_exynosCameraParameters->getHwPictureSize(&hwPictureW, &hwPictureH); |
| CLOGI("(%s):HW Picture width x height = %dx%d", __FUNCTION__, hwPictureW, hwPictureH); |
| m_exynosCameraParameters->getMaxPictureSize(&pictureMaxW, &pictureMaxH); |
| CLOGI("(%s):Picture MAX width x height = %dx%d", __FUNCTION__, pictureMaxW, pictureMaxH); |
| if( m_exynosCameraParameters->getHighSpeedRecording() ) { |
| m_exynosCameraParameters->getHwSensorSize(&sensorMaxW, &sensorMaxH); |
| CLOGI("(%s):HW Sensor(HighSpeed) MAX width x height = %dx%d", __FUNCTION__, sensorMaxW, sensorMaxH); |
| m_exynosCameraParameters->getHwPreviewSize(&previewMaxW, &previewMaxH); |
| CLOGI("(%s):HW Preview(HighSpeed) MAX width x height = %dx%d", __FUNCTION__, previewMaxW, previewMaxH); |
| } else { |
| m_exynosCameraParameters->getMaxSensorSize(&sensorMaxW, &sensorMaxH); |
| CLOGI("(%s):Sensor MAX width x height = %dx%d", __FUNCTION__, sensorMaxW, sensorMaxH); |
| m_exynosCameraParameters->getMaxPreviewSize(&previewMaxW, &previewMaxH); |
| CLOGI("(%s):Preview MAX width x height = %dx%d", __FUNCTION__, previewMaxW, previewMaxH); |
| } |
| |
| #if (SUPPORT_BACK_HW_VDIS || SUPPORT_FRONT_HW_VDIS) |
| /* |
| * we cannot expect TPU on or not, when open() api. |
| * so extract memory TPU size |
| */ |
| int w = 0, h = 0; |
| m_exynosCameraParameters->calcNormalToTpuSize(previewMaxW, previewMaxH, &w, &h); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):Hw vdis buffer calulation fail src(%d x %d) dst(%d x %d)",__FUNCTION__, __LINE__, previewMaxW, previewMaxH, w, h); |
| } |
| previewMaxW = w; |
| previewMaxH = h; |
| CLOGI("(%s): TPU based Preview MAX width x height = %dx%d", __FUNCTION__, previewMaxW, previewMaxH); |
| #endif |
| |
| m_exynosCameraParameters->getPreviewBdsSize(&bdsRect); |
| |
| /* FLITE */ |
| #ifdef CAMERA_PACKED_BAYER_ENABLE |
| #ifdef DEBUG_RAWDUMP |
| if (m_exynosCameraParameters->checkBayerDumpEnable()) { |
| bytesPerLine[0] = sensorMaxW * 2; |
| planeSize[0] = sensorMaxW * sensorMaxH * 2; |
| } else |
| #endif /* DEBUG_RAWDUMP */ |
| { |
| bytesPerLine[0] = ROUND_UP(sensorMaxW , 10) * 8 / 5; |
| planeSize[0] = bytesPerLine[0] * sensorMaxH; |
| } |
| #else |
| if (m_exynosCameraParameters->getBayerFormat() == V4L2_PIX_FMT_SBGGR12) { |
| bytesPerLine[0] = ROUND_UP(sensorMaxW , 10) * 8 / 5; |
| planeSize[0] = bytesPerLine[0] * sensorMaxH; |
| } else { |
| bytesPerLine[0] = sensorMaxW * 2; |
| planeSize[0] = sensorMaxW * sensorMaxH * 2; |
| } |
| #endif |
| planeCount = 2; |
| |
| /* TO DO : make num of buffers samely */ |
| maxBufferCount = m_exynosconfig->current->bufInfo.num_bayer_buffers; |
| #ifdef RESERVED_MEMORY_ENABLE |
| if (getCameraId() == CAMERA_ID_BACK) { |
| m_bayerBufferMgr->setContigBufCount(RESERVED_NUM_BAYER_BUFFERS); |
| |
| #ifdef CAMERA_ADD_BAYER_ENABLE |
| type = EXYNOS_CAMERA_BUFFER_ION_CACHED_RESERVED_TYPE; |
| |
| ret = m_allocBuffers(m_bayerBufferMgr, planeCount, planeSize, bytesPerLine, |
| maxBufferCount, maxBufferCount, type, true, true); |
| #else |
| type = EXYNOS_CAMERA_BUFFER_ION_RESERVED_TYPE; |
| |
| ret = m_allocBuffers(m_bayerBufferMgr, planeCount, planeSize, bytesPerLine, |
| maxBufferCount, maxBufferCount, type, true, false); |
| #endif |
| } else { |
| if (m_exynosCameraParameters->getDualMode() == false) { |
| type = EXYNOS_CAMERA_BUFFER_ION_RESERVED_TYPE; |
| m_bayerBufferMgr->setContigBufCount(FRONT_RESERVED_NUM_BAYER_BUFFERS); |
| } |
| ret = m_allocBuffers(m_bayerBufferMgr, planeCount, planeSize, bytesPerLine, |
| maxBufferCount, maxBufferCount, type, true, false); |
| } |
| #else |
| ret = m_allocBuffers(m_bayerBufferMgr, planeCount, planeSize, bytesPerLine, |
| maxBufferCount, maxBufferCount, type, true, false); |
| #endif |
| |
| if (ret < 0) { |
| if (getCameraId() == CAMERA_ID_FRONT && |
| type == EXYNOS_CAMERA_BUFFER_ION_RESERVED_TYPE){ |
| CLOGD("DEBUG(%s[%d]):can't alloc reserved memory of BayerBuffers(%d). so, change memory type", |
| __FUNCTION__, __LINE__, type); |
| |
| ret = m_allocBuffers(m_bayerBufferMgr, planeCount, planeSize, bytesPerLine, |
| maxBufferCount, maxBufferCount, EXYNOS_CAMERA_BUFFER_ION_NONCACHED_TYPE, true, false); |
| |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):bayerBuffer m_allocBuffers(bufferCount=%d) fail", |
| __FUNCTION__, __LINE__, maxBufferCount); |
| return ret; |
| } |
| } else { |
| CLOGE("ERR(%s[%d]):bayerBuffer m_allocBuffers(bufferCount=%d) fail", |
| __FUNCTION__, __LINE__, maxBufferCount); |
| return ret; |
| } |
| } |
| |
| type = EXYNOS_CAMERA_BUFFER_ION_NONCACHED_TYPE; |
| |
| #ifdef CAMERA_PACKED_BAYER_ENABLE |
| memset(&bytesPerLine, 0, sizeof(unsigned int) * EXYNOS_CAMERA_BUFFER_MAX_PLANES); |
| #else |
| if (m_exynosCameraParameters->getBayerFormat() == V4L2_PIX_FMT_SBGGR12) |
| memset(&bytesPerLine, 0, sizeof(unsigned int) * EXYNOS_CAMERA_BUFFER_MAX_PLANES); |
| #endif |
| /* for preview */ |
| planeSize[0] = 32 * 64 * 2; |
| planeCount = 2; |
| /* TO DO : make num of buffers samely */ |
| if (m_exynosCameraParameters->isFlite3aaOtf() == true) |
| maxBufferCount = m_exynosconfig->current->bufInfo.num_3aa_buffers; |
| else |
| maxBufferCount = m_exynosconfig->current->bufInfo.num_bayer_buffers; |
| |
| ret = m_allocBuffers(m_3aaBufferMgr, planeCount, planeSize, bytesPerLine, maxBufferCount, true, false); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_3aaBufferMgr m_allocBuffers(bufferCount=%d) fail", |
| __FUNCTION__, __LINE__, maxBufferCount); |
| return ret; |
| } |
| |
| #if defined (USE_ISP_BUFFER_SIZE_TO_BDS) |
| ispBufferW = bdsRect.w; |
| ispBufferH = bdsRect.h; |
| #else |
| ispBufferW = previewMaxW; |
| ispBufferH = previewMaxH; |
| #endif |
| |
| #ifdef CAMERA_PACKED_BAYER_ENABLE |
| bytesPerLine[0] = ROUND_UP((ispBufferW * 3 / 2), 16); |
| planeSize[0] = bytesPerLine[0] * ispBufferH; |
| #else |
| if (m_exynosCameraParameters->getBayerFormat() == V4L2_PIX_FMT_SBGGR12) { |
| bytesPerLine[0] = ROUND_UP((ispBufferW * 3 / 2), 16); |
| planeSize[0] = bytesPerLine[0] * ispBufferH; |
| } else { |
| bytesPerLine[0] = ispBufferW * 2; |
| planeSize[0] = ispBufferW * ispBufferH * 2; |
| } |
| #endif |
| |
| planeCount = 2; |
| /* TO DO : make num of buffers samely */ |
| if (m_exynosCameraParameters->is3aaIspOtf() == false) { |
| if (m_exynosCameraParameters->isFlite3aaOtf() == true) { |
| maxBufferCount = m_exynosconfig->current->bufInfo.num_3aa_buffers; |
| #ifdef RESERVED_MEMORY_ENABLE |
| if (getCameraId() == CAMERA_ID_BACK) { |
| type = EXYNOS_CAMERA_BUFFER_ION_RESERVED_TYPE; |
| if(m_exynosCameraParameters->getUHDRecordingMode() == true) { |
| m_ispBufferMgr->setContigBufCount(RESERVED_NUM_ISP_BUFFERS_ON_UHD); |
| } else { |
| m_ispBufferMgr->setContigBufCount(RESERVED_NUM_ISP_BUFFERS); |
| } |
| } else { |
| if (m_exynosCameraParameters->getDualMode() == false) { |
| type = EXYNOS_CAMERA_BUFFER_ION_RESERVED_TYPE; |
| m_ispBufferMgr->setContigBufCount(FRONT_RESERVED_NUM_ISP_BUFFERS); |
| } |
| } |
| #endif |
| } else { |
| maxBufferCount = m_exynosconfig->current->bufInfo.num_bayer_buffers; |
| #ifdef RESERVED_MEMORY_ENABLE |
| if (m_exynosCameraParameters->getDualMode() == false) { |
| type = EXYNOS_CAMERA_BUFFER_ION_RESERVED_TYPE; |
| m_ispBufferMgr->setContigBufCount(FRONT_RESERVED_NUM_ISP_BUFFERS); |
| } |
| #endif |
| } |
| |
| ret = m_allocBuffers(m_ispBufferMgr, planeCount, planeSize, bytesPerLine, |
| maxBufferCount, maxBufferCount, type, true, false); |
| if (ret < 0) { |
| if (getCameraId() == CAMERA_ID_FRONT && type == EXYNOS_CAMERA_BUFFER_ION_RESERVED_TYPE) { |
| CLOGD("DEBUG(%s[%d]):can't alloc reserved memory of IspBuffers(%d). so, change memory type", |
| __FUNCTION__, __LINE__, type); |
| ret = m_allocBuffers(m_ispBufferMgr, |
| planeCount, |
| planeSize, |
| bytesPerLine, |
| maxBufferCount, |
| maxBufferCount, |
| EXYNOS_CAMERA_BUFFER_ION_NONCACHED_TYPE, |
| true, |
| false); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_ispBufferMgr m_allocBuffers(bufferCount=%d) fail", |
| __FUNCTION__, __LINE__, maxBufferCount); |
| return ret; |
| } |
| } else { |
| CLOGE("ERR(%s[%d]):m_ispBufferMgr m_allocBuffers(bufferCount=%d) fail", |
| __FUNCTION__, __LINE__, maxBufferCount); |
| return ret; |
| } |
| } |
| } else { |
| CLOGD("DEBUG(%s[%d]):SKIP m_ispBufferMgr m_allocBuffers(bufferCount=%d) by 3aaIspOtf", |
| __FUNCTION__, __LINE__, maxBufferCount); |
| } |
| |
| /* HW VDIS memory */ |
| if (m_exynosCameraParameters->getTpuEnabledMode() == true) { |
| maxBufferCount = m_exynosconfig->current->bufInfo.num_hwdis_buffers; |
| |
| /* DIS MEMORY */ |
| int disFormat = m_exynosCameraParameters->getHWVdisFormat(); |
| unsigned int bpp = 0; |
| unsigned int disPlanes = 0; |
| |
| getYuvFormatInfo(disFormat, &bpp, &disPlanes); |
| |
| switch (disFormat) { |
| case V4L2_PIX_FMT_YUYV: |
| planeSize[0] = ALIGN_UP(bdsRect.w, TDNR_WIDTH_ALIGN) * ALIGN_UP(bdsRect.h, TDNR_HEIGHT_ALIGN) * 2; |
| break; |
| default: |
| CLOGE("ERR(%s[%d]):unexpected VDIS format(%d). so, fail", __FUNCTION__, __LINE__, disFormat); |
| return INVALID_OPERATION; |
| break; |
| } |
| |
| exynos_camera_buffer_type_t type = EXYNOS_CAMERA_BUFFER_ION_CACHED_TYPE; |
| |
| ret = m_allocBuffers(m_hwDisBufferMgr, planeCount, planeSize, bytesPerLine, maxBufferCount, maxBufferCount, type, true, false); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_hwDisBufferMgr m_allocBuffers(bufferCount=%d) fail", |
| __FUNCTION__, __LINE__, maxBufferCount); |
| return ret; |
| } |
| |
| CLOGD("DEBUG(%s[%d]):m_allocBuffers(m_hwDisBufferMgr): %d x %d, planeCount(%d), maxBufferCount(%d)", |
| __FUNCTION__, __LINE__, bdsRect.w, bdsRect.h, planeCount, maxBufferCount); |
| } |
| |
| #ifdef SAMSUNG_LBP |
| planeSize[0] = hwPreviewW * hwPreviewH; |
| planeSize[1] = hwPreviewW * hwPreviewH / 2; |
| planeCount = 3; |
| |
| maxBufferCount = m_exynosCameraParameters->getHoldFrameCount(); |
| |
| type = EXYNOS_CAMERA_BUFFER_ION_CACHED_TYPE; |
| |
| ret = m_allocBuffers(m_lbpBufferMgr, planeCount, planeSize, bytesPerLine, maxBufferCount, maxBufferCount, type, true, true); |
| if (ret < 0) { |
| CLOGE("[LBP]ERR(%s[%d]):m_lbpBufferMgr m_allocBuffers(bufferCount=%d) fail", |
| __FUNCTION__, __LINE__, maxBufferCount); |
| return ret; |
| } |
| #endif |
| |
| planeSize[0] = hwPreviewW * hwPreviewH; |
| planeSize[1] = hwPreviewW * hwPreviewH / 2; |
| planeCount = 3; |
| if(m_exynosCameraParameters->increaseMaxBufferOfPreview()){ |
| maxBufferCount = m_exynosCameraParameters->getPreviewBufferCount(); |
| } else { |
| maxBufferCount = m_exynosconfig->current->bufInfo.num_preview_buffers; |
| } |
| |
| bool needMmap = false; |
| if (m_previewWindow == NULL) |
| needMmap = true; |
| |
| ret = m_allocBuffers(m_scpBufferMgr, planeCount, planeSize, bytesPerLine, maxBufferCount, true, needMmap); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_scpBufferMgr m_allocBuffers(bufferCount=%d) fail", |
| __FUNCTION__, __LINE__, maxBufferCount); |
| return ret; |
| } |
| |
| if (m_exynosCameraParameters->getSupportedZoomPreviewWIthScaler()) { |
| planeSize[0] = ALIGN_UP(hwPreviewW, GSCALER_IMG_ALIGN) * ALIGN_UP(hwPreviewH, GSCALER_IMG_ALIGN); |
| planeSize[1] = ALIGN_UP(hwPreviewW, GSCALER_IMG_ALIGN) * ALIGN_UP(hwPreviewH, GSCALER_IMG_ALIGN) / 2; |
| planeCount = 3; |
| if(m_exynosCameraParameters->increaseMaxBufferOfPreview()){ |
| maxBufferCount = m_exynosCameraParameters->getPreviewBufferCount(); |
| } else { |
| maxBufferCount = m_exynosconfig->current->bufInfo.num_preview_buffers; |
| } |
| |
| bool needMmap = false; |
| if (m_previewWindow == NULL) |
| needMmap = true; |
| |
| ret = m_allocBuffers(m_zoomScalerBufferMgr, planeCount, planeSize, bytesPerLine, maxBufferCount, true, needMmap); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_scpBufferMgr m_allocBuffers(bufferCount=%d) fail", |
| __FUNCTION__, __LINE__, maxBufferCount); |
| return ret; |
| } |
| } |
| #ifdef SUPPORT_SW_VDIS |
| if(m_swVDIS_Mode) { |
| VDIS_LOG("VDIS_HAL: m_allocBuffers(m_scpBufferMgr): %d x %d", hwPreviewW, hwPreviewH); |
| |
| m_swVDIS_AdjustPreviewSize(&hwPreviewW, &hwPreviewH); |
| |
| planeSize[0] = ROUND_UP(hwPreviewW, CAMERA_MAGIC_ALIGN) * ROUND_UP(hwPreviewH, CAMERA_MAGIC_ALIGN) + MFC_7X_BUFFER_OFFSET; |
| planeSize[1] = ROUND_UP(hwPreviewW, CAMERA_MAGIC_ALIGN) * ROUND_UP(hwPreviewH / 2, CAMERA_MAGIC_ALIGN) + + MFC_7X_BUFFER_OFFSET; |
| planeCount = 3; |
| maxBufferCount = NUM_VDIS_BUFFERS; |
| exynos_camera_buffer_type_t swVDIS_type = EXYNOS_CAMERA_BUFFER_ION_NONCACHED_TYPE; |
| buffer_manager_allocation_mode_t swVDIS_allocMode = BUFFER_MANAGER_ALLOCATION_ATONCE; |
| |
| VDIS_LOG("VDIS_HAL: m_allocBuffers(m_swVDIS_BufferMgr): %d x %d", hwPreviewW, hwPreviewH); |
| |
| ret = m_allocBuffers(m_swVDIS_BufferMgr, planeCount, planeSize, bytesPerLine, maxBufferCount, maxBufferCount, swVDIS_type, swVDIS_allocMode, true, true); |
| |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_swVDIS_BufferMgr m_allocBuffers(bufferCount=%d) fail", |
| __FUNCTION__, __LINE__, maxBufferCount); |
| return ret; |
| } |
| |
| m_exynosCameraParameters->getHwPreviewSize(&hwPreviewW, &hwPreviewH); |
| } |
| #endif /*SUPPORT_SW_VDIS*/ |
| |
| #ifdef USE_BUFFER_WITH_STRIDE |
| int stride = m_scpBufferMgr->getBufStride(); |
| if (stride != hwPreviewW) { |
| CLOGI("INFO(%s[%d]):hwPreviewW(%d), stride(%d)", __FUNCTION__, __LINE__, hwPreviewW, stride); |
| if (stride == 0) { |
| /* If the SCP buffer manager is not instance of GrallocExynosCameraBufferManager |
| (In case of setPreviewWindow(null) is called), return value of setHwPreviewStride() |
| will be zero. If this value is passed as SCP width to firmware, firmware will |
| generate PABORT error. */ |
| CLOGW("WARN(%s[%d]):HACK: Invalid stride(%d). It will be replaced as hwPreviewW(%d) value.", |
| __FUNCTION__, __LINE__, stride, hwPreviewW); |
| stride = hwPreviewW; |
| } |
| } |
| #endif |
| |
| m_exynosCameraParameters->setHwPreviewStride(stride); |
| |
| if (m_exynosCameraParameters->isSccCapture() == true) { |
| m_exynosCameraParameters->getHwPictureSize(&hwPictureW, &hwPictureH); |
| CLOGI("(%s):HW Picture width x height = %dx%d", __FUNCTION__, hwPictureW, hwPictureH); |
| if (SCC_OUTPUT_COLOR_FMT == V4L2_PIX_FMT_NV21M) { |
| planeSize[0] = ALIGN_UP(hwPictureW, GSCALER_IMG_ALIGN) * ALIGN_UP(hwPictureH, GSCALER_IMG_ALIGN); |
| planeSize[1] = ALIGN_UP(hwPictureW, GSCALER_IMG_ALIGN) * ALIGN_UP(hwPictureH, GSCALER_IMG_ALIGN) / 2; |
| planeCount = 3; |
| } else if (SCC_OUTPUT_COLOR_FMT == V4L2_PIX_FMT_NV21) { |
| planeSize[0] = ALIGN_UP(hwPictureW, GSCALER_IMG_ALIGN) * ALIGN_UP(hwPictureH, GSCALER_IMG_ALIGN) * 3 / 2; |
| planeCount = 2; |
| } else { |
| planeSize[0] = ALIGN_UP(hwPictureW, GSCALER_IMG_ALIGN) * ALIGN_UP(hwPictureH, GSCALER_IMG_ALIGN) * 2; |
| planeCount = 2; |
| } |
| /* TO DO : make same num of buffers */ |
| if (m_exynosCameraParameters->isFlite3aaOtf() == true) |
| maxBufferCount = m_exynosconfig->current->bufInfo.num_picture_buffers; |
| else |
| maxBufferCount = m_exynosconfig->current->bufInfo.num_bayer_buffers; |
| |
| ret = m_allocBuffers(m_sccBufferMgr, planeCount, planeSize, bytesPerLine, maxBufferCount, true, false); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_sccBufferMgr m_allocBuffers(bufferCount=%d) fail", |
| __FUNCTION__, __LINE__, maxBufferCount); |
| return ret; |
| } |
| } |
| |
| CLOGI("INFO(%s[%d]):alloc buffer done - camera ID: %d", |
| __FUNCTION__, __LINE__, m_cameraId); |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_setReprocessingBuffer(void) |
| { |
| int ret = 0; |
| int pictureMaxW, pictureMaxH; |
| unsigned int planeSize[EXYNOS_CAMERA_BUFFER_MAX_PLANES] = {0}; |
| unsigned int bytesPerLine[EXYNOS_CAMERA_BUFFER_MAX_PLANES] = {0}; |
| int planeCount = 0; |
| int bufferCount = 0; |
| int minBufferCount = NUM_REPROCESSING_BUFFERS; |
| int maxBufferCount = NUM_PICTURE_BUFFERS; |
| exynos_camera_buffer_type_t type = EXYNOS_CAMERA_BUFFER_ION_NONCACHED_TYPE; |
| buffer_manager_allocation_mode_t allocMode = BUFFER_MANAGER_ALLOCATION_ONDEMAND; |
| |
| m_exynosCameraParameters->getMaxPictureSize(&pictureMaxW, &pictureMaxH); |
| CLOGI("(%s):HW Picture MAX width x height = %dx%d", __FUNCTION__, pictureMaxW, pictureMaxH); |
| |
| /* for reprocessing */ |
| #ifdef CAMERA_PACKED_BAYER_ENABLE |
| #ifdef DEBUG_RAWDUMP |
| if (m_exynosCameraParameters->checkBayerDumpEnable()) { |
| bytesPerLine[0] = pictureMaxW * 2; |
| planeSize[0] = pictureMaxW * pictureMaxH * 2; |
| } else |
| #endif /* DEBUG_RAWDUMP */ |
| { |
| bytesPerLine[0] = ROUND_UP((pictureMaxW * 3 / 2), 16); |
| planeSize[0] = bytesPerLine[0] * pictureMaxH; |
| } |
| #else |
| if (m_exynosCameraParameters->getBayerFormat() == V4L2_PIX_FMT_SBGGR12) { |
| bytesPerLine[0] = ROUND_UP((pictureMaxW * 3 / 2), 16); |
| planeSize[0] = bytesPerLine[0] * pictureMaxH; |
| } else { |
| bytesPerLine[0] = pictureMaxW * 2; |
| planeSize[0] = pictureMaxW * pictureMaxH * 2; |
| } |
| #endif |
| planeCount = 2; |
| bufferCount = NUM_REPROCESSING_BUFFERS; |
| |
| if (m_exynosCameraParameters->getHighResolutionCallbackMode() == true) { |
| /* ISP Reprocessing Buffer realloc for high resolution callback */ |
| minBufferCount = 2; |
| } |
| |
| ret = m_allocBuffers(m_ispReprocessingBufferMgr, planeCount, planeSize, bytesPerLine, minBufferCount, maxBufferCount, type, allocMode, true, false); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_ispReprocessingBufferMgr m_allocBuffers(minBufferCount=%d/maxBufferCount=%d) fail", |
| __FUNCTION__, __LINE__, minBufferCount, maxBufferCount); |
| return ret; |
| } |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_setPreviewCallbackBuffer(void) |
| { |
| int ret = 0; |
| int previewW = 0, previewH = 0; |
| int previewFormat = 0; |
| m_exynosCameraParameters->getPreviewSize(&previewW, &previewH); |
| previewFormat = m_exynosCameraParameters->getPreviewFormat(); |
| |
| unsigned int planeSize[EXYNOS_CAMERA_BUFFER_MAX_PLANES] = {0}; |
| unsigned int bytesPerLine[EXYNOS_CAMERA_BUFFER_MAX_PLANES] = {0}; |
| |
| int planeCount = getYuvPlaneCount(previewFormat); |
| int bufferCount = 1; |
| exynos_camera_buffer_type_t type = EXYNOS_CAMERA_BUFFER_ION_CACHED_TYPE; |
| |
| if (m_previewCallbackBufferMgr == NULL) { |
| CLOGE("ERR(%s[%d]): m_previewCallbackBufferMgr is NULL", __FUNCTION__, __LINE__); |
| return INVALID_OPERATION; |
| } |
| |
| if (m_previewCallbackBufferMgr->isAllocated() == true) { |
| if (m_exynosCameraParameters->getRestartPreview() == true) { |
| CLOGD("DEBUG(%s[%d]): preview size is changed, realloc buffer", __FUNCTION__, __LINE__); |
| m_previewCallbackBufferMgr->deinit(); |
| } else { |
| return NO_ERROR; |
| } |
| } |
| |
| ret = getYuvPlaneSize(previewFormat, planeSize, previewW, previewH); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): BAD value, format(%x), size(%dx%d)", |
| __FUNCTION__, __LINE__, previewFormat, previewW, previewH); |
| return ret; |
| } |
| |
| ret = m_allocBuffers(m_previewCallbackBufferMgr, planeCount, planeSize, bytesPerLine, bufferCount, bufferCount, type, false, false); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_previewCallbackBufferMgr m_allocBuffers(bufferCount=%d) fail", |
| __FUNCTION__, __LINE__, bufferCount); |
| return ret; |
| } |
| |
| return NO_ERROR; |
| } |
| |
| bool ExynosCamera::m_startPictureBufferThreadFunc(void) |
| { |
| int ret = 0; |
| |
| ret = m_setPictureBuffer(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_setPictureBuffer failed", __FUNCTION__, __LINE__); |
| |
| /* TODO: Need release buffers and error exit */ |
| |
| return false; |
| } |
| |
| return false; |
| } |
| |
| status_t ExynosCamera::m_setPictureBuffer(void) |
| { |
| int ret = 0; |
| unsigned int planeSize[3] = {0}; |
| unsigned int bytesPerLine[3] = {0}; |
| int pictureW = 0, pictureH = 0, pictureFormat = 0; |
| int planeCount = 0; |
| int minBufferCount = 1; |
| int maxBufferCount = 1; |
| exynos_camera_buffer_type_t type = EXYNOS_CAMERA_BUFFER_ION_NONCACHED_TYPE; |
| buffer_manager_allocation_mode_t allocMode = BUFFER_MANAGER_ALLOCATION_ONDEMAND; |
| int sensorMaxW, sensorMaxH; |
| |
| m_exynosCameraParameters->getMaxPictureSize(&pictureW, &pictureH); |
| pictureFormat = m_exynosCameraParameters->getPictureFormat(); |
| |
| m_exynosCameraParameters->getMaxSensorSize(&sensorMaxW, &sensorMaxH); |
| CLOGI("(%s):Sensor MAX width x height = %dx%d", __FUNCTION__, sensorMaxW, sensorMaxH); |
| |
| #ifdef SAMSUNG_DNG |
| if(m_exynosCameraParameters->getDNGCaptureModeOn()) { |
| type = EXYNOS_CAMERA_BUFFER_ION_CACHED_TYPE; |
| bytesPerLine[0] = sensorMaxW * 2; |
| planeSize[0] = sensorMaxW * sensorMaxH * 2 + DNG_HEADER_LIMIT_SIZE; |
| planeCount = 2; |
| maxBufferCount = 4; |
| |
| ret = m_allocBuffers(m_fliteBufferMgr, planeCount, planeSize, bytesPerLine, maxBufferCount, maxBufferCount, type, true, true); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):bayerBuffer m_allocBuffers(bufferCount=%d) fail", |
| __FUNCTION__, __LINE__, maxBufferCount); |
| return ret; |
| } |
| } |
| #endif |
| |
| if ((needGSCForCapture(getCameraId()) == true) |
| #if 0 // SAMSUNG_MAGICSHOT |
| || ((m_exynosCameraParameters->isReprocessing() == true) && (m_exynosCameraParameters->getShotMode() == SHOT_MODE_MAGIC)) |
| #endif |
| ) { |
| #if 0 // SAMSUNG_MAGICSHOT_OLD |
| if ((m_exynosCameraParameters->isReprocessing() == true) && (m_exynosCameraParameters->getShotMode() == SHOT_MODE_MAGIC)) { |
| int previewW = 0, previewH = 0; |
| m_exynosCameraParameters->getPreviewSize(&previewW, &previewH); |
| planeSize[0] = previewW * previewH * 1.5; |
| planeCount = 1; |
| } else |
| #endif |
| { |
| if (JPEG_INPUT_COLOR_FMT == V4L2_PIX_FMT_NV21M) { |
| planeSize[0] = ALIGN_UP(pictureW, GSCALER_IMG_ALIGN) * ALIGN_UP(pictureH, GSCALER_IMG_ALIGN); |
| planeSize[1] = ALIGN_UP(pictureW, GSCALER_IMG_ALIGN) * ALIGN_UP(pictureH, GSCALER_IMG_ALIGN) / 2; |
| planeCount = 2; |
| } else if (JPEG_INPUT_COLOR_FMT == V4L2_PIX_FMT_NV21) { |
| planeSize[0] = ALIGN_UP(pictureW, GSCALER_IMG_ALIGN) * ALIGN_UP(pictureH, GSCALER_IMG_ALIGN) * 3 / 2; |
| planeCount = 1; |
| } else { |
| planeSize[0] = ALIGN_UP(pictureW, GSCALER_IMG_ALIGN) * ALIGN_UP(pictureH, GSCALER_IMG_ALIGN) * 2; |
| planeCount = 1; |
| } |
| } |
| minBufferCount = 1; |
| #ifdef SAMSUNG_LLS_DEBLUR |
| maxBufferCount = MAX_LD_CAPTURE_COUNT; |
| #else |
| maxBufferCount = m_exynosconfig->current->bufInfo.num_picture_buffers; |
| #endif |
| |
| // Pre-allocate certain amount of buffers enough to fed into 3 JPEG save threads. |
| if (m_exynosCameraParameters->getSeriesShotCount() > 0) |
| minBufferCount = NUM_BURST_GSC_JPEG_INIT_BUFFER; |
| |
| #if !defined(SAMSUNG_DEBLUR) && !defined(SAMSUNG_LLS_DEBLUR) |
| type = EXYNOS_CAMERA_BUFFER_ION_NONCACHED_TYPE; |
| ret = m_allocBuffers(m_gscBufferMgr, planeCount, planeSize, |
| bytesPerLine, minBufferCount, maxBufferCount, type, allocMode, false, false); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_gscBufferMgr m_allocBuffers(minBufferCount=%d, maxBufferCount=%d) fail", |
| __FUNCTION__, __LINE__, minBufferCount, maxBufferCount); |
| return ret; |
| } |
| #else |
| type = EXYNOS_CAMERA_BUFFER_ION_CACHED_TYPE; |
| ret = m_allocBuffers(m_gscBufferMgr, planeCount, planeSize, |
| bytesPerLine, minBufferCount, maxBufferCount, type, allocMode, false, true); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_gscBufferMgr m_allocBuffers(minBufferCount=%d, maxBufferCount=%d) fail", |
| __FUNCTION__, __LINE__, minBufferCount, maxBufferCount); |
| return ret; |
| } |
| #endif |
| } |
| |
| if (needGSCForCapture(getCameraId()) == true) { |
| int f_previewW = 0, f_previewH = 0; |
| m_exynosCameraParameters->getPreviewSize(&f_previewW, &f_previewH); |
| planeSize[0] = f_previewW * f_previewH * 1.5; |
| planeCount = 1; |
| #if defined (SAMSUNG_BD) || defined (SAMSUNG_DEBLUR) |
| /* Change the MagicGSCBuffer type to mmap & cached for the performance enhancement*/ |
| type = EXYNOS_CAMERA_BUFFER_ION_CACHED_TYPE; |
| ret = m_allocBuffers(m_postPictureGscBufferMgr, planeCount, planeSize, |
| bytesPerLine, minBufferCount, maxBufferCount, type, allocMode, false, true); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_gscBufferMgr m_allocBuffers(minBufferCount=%d, maxBufferCount=%d) fail", |
| __FUNCTION__, __LINE__, minBufferCount, maxBufferCount); |
| return ret; |
| } |
| #else |
| type = EXYNOS_CAMERA_BUFFER_ION_NONCACHED_TYPE; |
| ret = m_allocBuffers(m_postPictureGscBufferMgr, planeCount, planeSize, |
| bytesPerLine, minBufferCount, maxBufferCount, type, allocMode, false, false); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_gscBufferMgr m_allocBuffers(minBufferCount=%d, maxBufferCount=%d) fail", |
| __FUNCTION__, __LINE__, minBufferCount, maxBufferCount); |
| return ret; |
| } |
| #endif |
| } |
| |
| if(m_exynosCameraParameters->getSamsungCamera()) { |
| int thumbnailW = 0, thumbnailH = 0; |
| m_exynosCameraParameters->getThumbnailSize(&thumbnailW, &thumbnailH); |
| if (thumbnailW > 0 && thumbnailH > 0) { |
| planeSize[0] = FRAME_SIZE(HAL_PIXEL_FORMAT_RGBA_8888, thumbnailW, thumbnailH); |
| planeCount = 1; |
| maxBufferCount = NUM_THUMBNAIL_POSTVIEW_BUFFERS; |
| type = EXYNOS_CAMERA_BUFFER_ION_NONCACHED_TYPE; |
| |
| ret = m_allocBuffers(m_thumbnailGscBufferMgr, planeCount, planeSize, |
| bytesPerLine, maxBufferCount, maxBufferCount, type, allocMode, false, true); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_gscBufferMgr m_allocBuffers(minBufferCount=%d, maxBufferCount=%d) fail", |
| __FUNCTION__, __LINE__, maxBufferCount, maxBufferCount); |
| return ret; |
| } |
| } |
| } |
| |
| if( m_hdrEnabled == false ) { |
| if (JPEG_INPUT_COLOR_FMT == V4L2_PIX_FMT_NV21M) { |
| planeSize[0] = pictureW * pictureH * 3 / 2; |
| planeCount = 2; |
| } else if (JPEG_INPUT_COLOR_FMT == V4L2_PIX_FMT_NV21) { |
| planeSize[0] = pictureW * pictureH * 3 / 2; |
| planeCount = 1; |
| } else { |
| planeSize[0] = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(pictureFormat), pictureW, pictureH); |
| planeCount = 1; |
| } |
| minBufferCount = 1; |
| maxBufferCount = m_exynosconfig->current->bufInfo.num_picture_buffers; |
| |
| type = EXYNOS_CAMERA_BUFFER_ION_CACHED_TYPE; |
| CLOGD("DEBUG(%s[%d]): jpegBuffer picture(%dx%d) size(%d)", __FUNCTION__, __LINE__, pictureW, pictureH, planeSize[0]); |
| |
| // Same with above GSC buffers |
| if (m_exynosCameraParameters->getSeriesShotCount() > 0) |
| minBufferCount = NUM_BURST_GSC_JPEG_INIT_BUFFER; |
| |
| #ifdef RESERVED_MEMORY_ENABLE |
| if (getCameraId() == CAMERA_ID_BACK |
| #ifdef RESERVED_MEMORY_20M_WORKAROUND |
| && m_cameraSensorId != SENSOR_NAME_S5K2T2 |
| #endif |
| ) { |
| #ifdef CAMERA_PACKED_BAYER_ENABLE |
| type = EXYNOS_CAMERA_BUFFER_ION_CACHED_RESERVED_TYPE; |
| #else |
| /* More reserved memory is needed when using unpack bayer */ |
| type = EXYNOS_CAMERA_BUFFER_ION_CACHED_TYPE; |
| #endif |
| if (m_exynosCameraParameters->getUHDRecordingMode() == true) { |
| m_jpegBufferMgr->setContigBufCount(RESERVED_NUM_JPEG_BUFFERS_ON_UHD); |
| } else { |
| m_jpegBufferMgr->setContigBufCount(RESERVED_NUM_JPEG_BUFFERS); |
| |
| /* alloc at once */ |
| minBufferCount = NUM_BURST_GSC_JPEG_INIT_BUFFER; |
| } |
| } |
| #endif |
| |
| ret = m_allocBuffers(m_jpegBufferMgr, planeCount, planeSize, bytesPerLine, |
| minBufferCount, maxBufferCount, type, allocMode, false, true); |
| if (ret < 0) { |
| if (getCameraId() == CAMERA_ID_FRONT && type == EXYNOS_CAMERA_BUFFER_ION_CACHED_RESERVED_TYPE) { |
| CLOGD("DEBUG(%s[%d]):can't alloc reserved memory of JpegBuffers(%d). so, change memory type", |
| __FUNCTION__, __LINE__, type); |
| |
| ret = m_allocBuffers(m_jpegBufferMgr, |
| planeCount, |
| planeSize, |
| bytesPerLine, |
| minBufferCount, |
| maxBufferCount, |
| EXYNOS_CAMERA_BUFFER_ION_CACHED_TYPE, |
| allocMode, |
| false, |
| true); |
| if (ret < 0) { |
| CLOGE("ERR(%s:%d):jpegSrcHeapBuffer m_allocBuffers(bufferCount=%d) fail", |
| __FUNCTION__, __LINE__, NUM_REPROCESSING_BUFFERS); |
| } |
| } else { |
| CLOGE("ERR(%s:%d):jpegSrcHeapBuffer m_allocBuffers(bufferCount=%d) fail", |
| __FUNCTION__, __LINE__, NUM_REPROCESSING_BUFFERS); |
| } |
| } |
| } |
| |
| return ret; |
| } |
| |
| status_t ExynosCamera::m_releaseBuffers(void) |
| { |
| CLOGI("INFO(%s[%d]):release buffer", __FUNCTION__, __LINE__); |
| int ret = 0; |
| |
| if (m_bayerBufferMgr != NULL) { |
| m_bayerBufferMgr->deinit(); |
| } |
| #ifdef SAMSUNG_DNG |
| if (m_fliteBufferMgr != NULL) { |
| m_fliteBufferMgr->deinit(); |
| } |
| #endif |
| if (m_3aaBufferMgr != NULL) { |
| m_3aaBufferMgr->deinit(); |
| } |
| if (m_ispBufferMgr != NULL) { |
| m_ispBufferMgr->deinit(); |
| } |
| if (m_hwDisBufferMgr != NULL) { |
| m_hwDisBufferMgr->deinit(); |
| } |
| if (m_scpBufferMgr != NULL) { |
| m_scpBufferMgr->deinit(); |
| } |
| if (m_ispReprocessingBufferMgr != NULL) { |
| m_ispReprocessingBufferMgr->deinit(); |
| } |
| if (m_sccReprocessingBufferMgr != NULL) { |
| m_sccReprocessingBufferMgr->deinit(); |
| } |
| if (m_sccBufferMgr != NULL) { |
| m_sccBufferMgr->deinit(); |
| } |
| if (m_gscBufferMgr != NULL) { |
| m_gscBufferMgr->deinit(); |
| } |
| |
| if (m_postPictureGscBufferMgr != NULL) { |
| m_postPictureGscBufferMgr->deinit(); |
| } |
| |
| if (m_thumbnailGscBufferMgr != NULL) { |
| m_thumbnailGscBufferMgr->deinit(); |
| } |
| |
| #ifdef SAMSUNG_LBP |
| if (m_lbpBufferMgr != NULL) { |
| m_lbpBufferMgr->deinit(); |
| } |
| #endif |
| |
| if (m_jpegBufferMgr != NULL) { |
| m_jpegBufferMgr->deinit(); |
| } |
| if (m_recordingBufferMgr != NULL) { |
| m_recordingBufferMgr->deinit(); |
| } |
| if (m_previewCallbackBufferMgr != NULL) { |
| m_previewCallbackBufferMgr->deinit(); |
| } |
| if (m_highResolutionCallbackBufferMgr != NULL) { |
| m_highResolutionCallbackBufferMgr->deinit(); |
| } |
| #ifdef SUPPORT_SW_VDIS |
| if (m_swVDIS_BufferMgr != NULL) { |
| m_swVDIS_BufferMgr->deinit(); |
| } |
| #endif /*SUPPORT_SW_VDIS*/ |
| |
| CLOGI("INFO(%s[%d]):free buffer done", __FUNCTION__, __LINE__); |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_putBuffers(ExynosCameraBufferManager *bufManager, int bufIndex) |
| { |
| if (bufManager != NULL) |
| bufManager->putBuffer(bufIndex, EXYNOS_CAMERA_BUFFER_POSITION_NONE); |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_allocBuffers( |
| ExynosCameraBufferManager *bufManager, |
| int planeCount, |
| unsigned int *planeSize, |
| unsigned int *bytePerLine, |
| int reqBufCount, |
| bool createMetaPlane, |
| bool needMmap) |
| { |
| int ret = 0; |
| |
| ret = m_allocBuffers( |
| bufManager, |
| planeCount, |
| planeSize, |
| bytePerLine, |
| reqBufCount, |
| reqBufCount, |
| EXYNOS_CAMERA_BUFFER_ION_NONCACHED_TYPE, |
| BUFFER_MANAGER_ALLOCATION_ATONCE, |
| createMetaPlane, |
| needMmap); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_allocBuffers(reqBufCount=%d) fail", |
| __FUNCTION__, __LINE__, reqBufCount); |
| } |
| |
| return ret; |
| } |
| |
| status_t ExynosCamera::m_allocBuffers( |
| ExynosCameraBufferManager *bufManager, |
| int planeCount, |
| unsigned int *planeSize, |
| unsigned int *bytePerLine, |
| int minBufCount, |
| int maxBufCount, |
| exynos_camera_buffer_type_t type, |
| bool createMetaPlane, |
| bool needMmap) |
| { |
| int ret = 0; |
| |
| ret = m_allocBuffers( |
| bufManager, |
| planeCount, |
| planeSize, |
| bytePerLine, |
| minBufCount, |
| maxBufCount, |
| type, |
| BUFFER_MANAGER_ALLOCATION_ONDEMAND, |
| createMetaPlane, |
| needMmap); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_allocBuffers(minBufCount=%d, maxBufCount=%d, type=%d) fail", |
| __FUNCTION__, __LINE__, minBufCount, maxBufCount, type); |
| } |
| |
| return ret; |
| } |
| |
| status_t ExynosCamera::m_allocBuffers( |
| ExynosCameraBufferManager *bufManager, |
| int planeCount, |
| unsigned int *planeSize, |
| unsigned int *bytePerLine, |
| int minBufCount, |
| int maxBufCount, |
| exynos_camera_buffer_type_t type, |
| buffer_manager_allocation_mode_t allocMode, |
| bool createMetaPlane, |
| bool needMmap) |
| { |
| int ret = 0; |
| |
| CLOGI("INFO(%s[%d]):setInfo(planeCount=%d, minBufCount=%d, maxBufCount=%d, type=%d, allocMode=%d)", |
| __FUNCTION__, __LINE__, planeCount, minBufCount, maxBufCount, (int)type, (int)allocMode); |
| |
| ret = bufManager->setInfo( |
| planeCount, |
| planeSize, |
| bytePerLine, |
| 0, |
| minBufCount, |
| maxBufCount, |
| type, |
| allocMode, |
| createMetaPlane, |
| needMmap); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setInfo fail", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| ret = bufManager->alloc(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):alloc fail", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| func_exit: |
| |
| return ret; |
| } |
| |
| status_t ExynosCamera::m_checkThreadState(int *threadState, int *countRenew) |
| { |
| int ret = NO_ERROR; |
| |
| if ((*threadState == ERROR_POLLING_DETECTED) || (*countRenew > ERROR_DQ_BLOCKED_COUNT)) { |
| CLOGW("WRN(%s[%d]:SCP DQ Timeout! State:[%d], Duration:%d msec", __FUNCTION__, __LINE__, *threadState, (*countRenew)*(MONITOR_THREAD_INTERVAL/1000)); |
| ret = false; |
| } else { |
| CLOGV("[%s] (%d) (%d)", __FUNCTION__, __LINE__, *threadState); |
| ret = NO_ERROR; |
| } |
| |
| return ret; |
| } |
| |
| status_t ExynosCamera::m_checkThreadInterval(uint32_t pipeId, uint32_t pipeInterval, int *threadState) |
| { |
| uint64_t *threadInterval; |
| int ret = NO_ERROR; |
| |
| m_previewFrameFactory->getThreadInterval(&threadInterval, pipeId); |
| if (*threadInterval > pipeInterval) { |
| CLOGW("WRN(%s[%d]:Pipe(%d) Thread Interval [%llu msec], State:[%d]", __FUNCTION__, __LINE__, pipeId, (unsigned long long)(*threadInterval)/1000, *threadState); |
| ret = false; |
| } else { |
| CLOGV("Thread IntervalTime [%lld]", (unsigned long long)*threadInterval); |
| CLOGV("Thread Renew state [%d]", *threadState); |
| ret = NO_ERROR; |
| } |
| |
| return ret; |
| } |
| |
| bool ExynosCamera::m_monitorThreadFunc(void) |
| { |
| CLOGV("INFO(%s[%d]):", __FUNCTION__, __LINE__); |
| |
| int *threadState; |
| struct timeval dqTime; |
| uint64_t *timeInterval; |
| int *countRenew; |
| int camId = getCameraId(); |
| int ret = NO_ERROR; |
| int loopCount = 0; |
| |
| int dtpStatus = 0; |
| int pipeIdFlite = 0; |
| int pipeIdErrorCheck = 0; |
| |
| for (loopCount = 0; loopCount < MONITOR_THREAD_INTERVAL; loopCount += (MONITOR_THREAD_INTERVAL/20)) { |
| if (m_flagThreadStop == true) { |
| CLOGI("INFO(%s[%d]): m_flagThreadStop(%d)", __FUNCTION__, __LINE__, m_flagThreadStop); |
| |
| return false; |
| } |
| |
| usleep(MONITOR_THREAD_INTERVAL/20); |
| } |
| |
| if (m_previewFrameFactory == NULL) { |
| CLOGW("WARN(%s[%d]): m_previewFrameFactory is NULL. Skip monitoring.", __FUNCTION__, __LINE__); |
| |
| return false; |
| } |
| |
| pipeIdFlite = PIPE_FLITE; |
| |
| if (m_exynosCameraParameters->is3aaIspOtf() == true) { |
| if (m_exynosCameraParameters->getTpuEnabledMode() == true) |
| pipeIdErrorCheck = PIPE_DIS; |
| else |
| pipeIdErrorCheck = PIPE_3AA; |
| } else { |
| pipeIdErrorCheck = PIPE_ISP; |
| } |
| |
| #ifdef MONITOR_LOG_SYNC |
| uint32_t pipeIdIsp = 0; |
| |
| /* define pipe for isp node cause of sync log sctrl */ |
| if (m_exynosCameraParameters->isFlite3aaOtf() == true) { |
| if (m_exynosCameraParameters->is3aaIspOtf() == true) { |
| pipeIdIsp = PIPE_3AA; |
| } else { |
| pipeIdIsp = PIPE_ISP; |
| } |
| } else { |
| pipeIdIsp = PIPE_ISP; |
| } |
| |
| /* If it is not front camera in dual and sensor pipe is running, do sync log */ |
| if (m_previewFrameFactory->checkPipeThreadRunning(pipeIdIsp) && |
| !(getCameraId() == CAMERA_ID_FRONT && m_exynosCameraParameters->getDualMode())){ |
| if (!(m_syncLogDuration % MONITOR_LOG_SYNC_INTERVAL)) { |
| uint32_t syncLogId = m_getSyncLogId(); |
| CLOGI("INFO(%s[%d]): @FIMC_IS_SYNC %d", __FUNCTION__, __LINE__, syncLogId); |
| m_previewFrameFactory->syncLog(pipeIdIsp, syncLogId); |
| } |
| m_syncLogDuration++; |
| } |
| #endif |
| |
| m_previewFrameFactory->getControl(V4L2_CID_IS_G_DTPSTATUS, &dtpStatus, pipeIdFlite); |
| if (dtpStatus == 1) { |
| CLOGD("DEBUG(%s[%d]):DTP Detected. dtpStatus(%d)", __FUNCTION__, __LINE__, dtpStatus); |
| dump(); |
| |
| #ifdef CAMERA_GED_FEATURE |
| /* in GED */ |
| m_notifyCb(CAMERA_MSG_ERROR, 100, 0, m_callbackCookie); |
| #else |
| /* specifically defined */ |
| m_notifyCb(CAMERA_MSG_ERROR, 1002, 0, m_callbackCookie); |
| /* or */ |
| /* android_printAssert(NULL, LOG_TAG, "killed by itself"); */ |
| #endif |
| |
| return false; |
| } |
| |
| #ifdef SENSOR_OVERFLOW_CHECK |
| m_previewFrameFactory->getControl(V4L2_CID_IS_G_DTPSTATUS, &dtpStatus, pipeIdFlite); |
| if (dtpStatus == 1) { |
| CLOGD("DEBUG(%s[%d]):DTP Detected. dtpStatus(%d)", __FUNCTION__, __LINE__, dtpStatus); |
| dump(); |
| |
| /* in GED */ |
| /* m_notifyCb(CAMERA_MSG_ERROR, 100, 0, m_callbackCookie); */ |
| /* specifically defined */ |
| /* m_notifyCb(CAMERA_MSG_ERROR, 1002, 0, m_callbackCookie); */ |
| /* or */ |
| android_printAssert(NULL, LOG_TAG, "killed by itself"); |
| |
| return false; |
| } |
| #endif |
| |
| m_previewFrameFactory->getThreadState(&threadState, pipeIdErrorCheck); |
| m_previewFrameFactory->getThreadRenew(&countRenew, pipeIdErrorCheck); |
| |
| if (m_exynosCameraParameters->getSamsungCamera() && ((*threadState == ERROR_POLLING_DETECTED) || (*countRenew > ERROR_DQ_BLOCKED_COUNT))) { |
| CLOGD("DEBUG(%s[%d]):ESD Detected. threadState(%d) *countRenew(%d)", __FUNCTION__, __LINE__, *threadState, *countRenew); |
| dump(); |
| #ifdef SAMSUNG_TN_FEATURE |
| if (m_recordingEnabled == true |
| && m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_VIDEO_FRAME) |
| && m_recordingCallbackHeap != NULL |
| && m_callbackCookie != NULL) { |
| |
| CLOGD("DEBUG(%s[%d]):Timestamp callback with CAMERA_MSG_ERROR start", __FUNCTION__, __LINE__); |
| |
| m_dataCbTimestamp( |
| 0, |
| CAMERA_MSG_ERROR | CAMERA_MSG_VIDEO_FRAME, |
| m_recordingCallbackHeap, |
| 0, |
| m_callbackCookie); |
| |
| CLOGD("DEBUG(%s[%d]):Timestamp callback with CAMERA_MSG_ERROR end", __FUNCTION__, __LINE__); |
| } |
| #endif |
| |
| #ifdef CAMERA_GED_FEATURE |
| /* in GED */ |
| /* skip error callback */ |
| /* m_notifyCb(CAMERA_MSG_ERROR, 100, 0, m_callbackCookie); */ |
| #else |
| /* specifically defined */ |
| m_notifyCb(CAMERA_MSG_ERROR, 1001, 0, m_callbackCookie); |
| /* or */ |
| /* android_printAssert(NULL, LOG_TAG, "killed by itself"); */ |
| #endif |
| |
| ret = m_previewFrameFactory->setControl(V4L2_CID_IS_CAMERA_TYPE, IS_COLD_RESET, PIPE_3AA); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):PIPE_%d V4L2_CID_IS_CAMERA_TYPE fail, ret(%d)", __FUNCTION__, __LINE__, PIPE_3AA, ret); |
| } |
| |
| return false; |
| } else { |
| CLOGV("[%s] (%d) (%d)", __FUNCTION__, __LINE__, *threadState); |
| } |
| |
| #if 0 |
| m_checkThreadState(threadState, countRenew)?:ret = false; |
| m_checkThreadInterval(PIPE_SCP, WARNING_SCP_THREAD_INTERVAL, threadState)?:ret = false; |
| |
| enum pipeline pipe; |
| |
| /* check PIPE_3AA thread state & interval */ |
| if (m_exynosCameraParameters->isFlite3aaOtf() == true) { |
| pipe = PIPE_3AA_ISP; |
| |
| m_previewFrameFactory->getThreadRenew(&countRenew, pipe); |
| m_checkThreadState(threadState, countRenew)?:ret = false; |
| |
| if (ret == false) { |
| dump(); |
| |
| /* in GED */ |
| m_notifyCb(CAMERA_MSG_ERROR, 100, 0, m_callbackCookie); |
| /* specifically defined */ |
| /* m_notifyCb(CAMERA_MSG_ERROR, 1001, 0, m_callbackCookie); */ |
| /* or */ |
| android_printAssert(NULL, LOG_TAG, "killed by itself"); |
| } |
| } else { |
| pipe = PIPE_3AA; |
| |
| m_previewFrameFactory->getThreadRenew(&countRenew, pipe); |
| m_checkThreadState(threadState, countRenew)?:ret = false; |
| |
| if (ret == false) { |
| dump(); |
| |
| /* in GED */ |
| m_notifyCb(CAMERA_MSG_ERROR, 100, 0, m_callbackCookie); |
| /* specifically defined */ |
| /* m_notifyCb(CAMERA_MSG_ERROR, 1001, 0, m_callbackCookie); */ |
| /* or */ |
| android_printAssert(NULL, LOG_TAG, "killed by itself"); |
| } |
| } |
| |
| m_checkThreadInterval(pipe, WARNING_3AA_THREAD_INTERVAL, threadState)?:ret = false; |
| |
| if (m_callbackState == 0) { |
| m_callbackStateOld = 0; |
| m_callbackState = 0; |
| m_callbackMonitorCount = 0; |
| } else { |
| if (m_callbackStateOld != m_callbackState) { |
| m_callbackStateOld = m_callbackState; |
| CLOGD("INFO(%s[%d]):callback state is updated (0x%x)", __FUNCTION__, __LINE__, m_callbackStateOld); |
| } else { |
| if ((m_callbackStateOld & m_callbackState) != 0) |
| CLOGE("ERR(%s[%d]):callback is blocked (0x%x), Duration:%d msec", __FUNCTION__, __LINE__, m_callbackState, m_callbackMonitorCount*(MONITOR_THREAD_INTERVAL/1000)); |
| } |
| } |
| #endif |
| |
| gettimeofday(&dqTime, NULL); |
| m_previewFrameFactory->getThreadInterval(&timeInterval, pipeIdErrorCheck); |
| |
| CLOGV("Thread IntervalTime [%lld]", (long long)*timeInterval); |
| CLOGV("Thread Renew Count [%d]", *countRenew); |
| |
| m_previewFrameFactory->incThreadRenew(pipeIdErrorCheck); |
| |
| return true; |
| } |
| |
| #ifdef MONITOR_LOG_SYNC |
| uint32_t ExynosCamera::m_getSyncLogId(void) |
| { |
| return ++cameraSyncLogId; |
| } |
| #endif |
| |
| bool ExynosCamera::m_autoFocusResetNotify(__unused int focusMode) |
| { |
| #ifdef SAMSUNG_TN_FEATURE |
| /* show restart */ |
| CLOGD("DEBUG(%s):CAMERA_MSG_FOCUS(%d) mode(%d)", __func__, FOCUS_RESULT_RESTART, focusMode); |
| m_notifyCb(CAMERA_MSG_FOCUS, FOCUS_RESULT_RESTART, 0, m_callbackCookie); |
| |
| /* show focusing */ |
| CLOGD("DEBUG(%s):CAMERA_MSG_FOCUS(%d) mode(%d)", __func__, FOCUS_RESULT_FOCUSING, focusMode); |
| m_notifyCb(CAMERA_MSG_FOCUS, FOCUS_RESULT_FOCUSING, 0, m_callbackCookie); |
| #endif |
| return true; |
| } |
| |
| bool ExynosCamera::m_autoFocusThreadFunc(void) |
| { |
| CLOGI("INFO(%s[%d]): -IN-", __FUNCTION__, __LINE__); |
| |
| bool afResult = false; |
| int focusMode = 0; |
| ExynosCameraActivityAutofocus *autoFocusMgr = m_exynosCameraActivityControl->getAutoFocusMgr(); |
| |
| /* block until we're told to start. we don't want to use |
| * a restartable thread and requestExitAndWait() in cancelAutoFocus() |
| * because it would cause deadlock between our callbacks and the |
| * caller of cancelAutoFocus() which both want to grab the same lock |
| * in CameraServices layer. |
| */ |
| |
| if (getCameraId() == CAMERA_ID_FRONT) { |
| if (m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_FOCUS)) { |
| if (m_notifyCb != NULL) { |
| CLOGD("DEBUG(%s):Do not support autoFocus in front camera.", __FUNCTION__); |
| m_notifyCb(CAMERA_MSG_FOCUS, true, 0, m_callbackCookie); |
| } else { |
| CLOGD("DEBUG(%s):m_notifyCb is NULL!", __FUNCTION__); |
| } |
| } else { |
| CLOGD("DEBUG(%s):autoFocus msg disabled !!", __FUNCTION__); |
| } |
| return false; |
| } |
| |
| if (m_autoFocusType == AUTO_FOCUS_SERVICE) { |
| focusMode = m_exynosCameraParameters->getFocusMode(); |
| } else if (m_autoFocusType == AUTO_FOCUS_HAL) { |
| focusMode = FOCUS_MODE_AUTO; |
| |
| if (m_notifyCb != NULL) { |
| m_autoFocusResetNotify(focusMode); |
| } |
| } |
| |
| m_autoFocusLock.lock(); |
| /* check early exit request */ |
| if (m_exitAutoFocusThread == true) { |
| CLOGD("DEBUG(%s):exiting on request", __FUNCTION__); |
| goto done; |
| } |
| |
| m_autoFocusRunning = true; |
| |
| if (m_autoFocusRunning == true) { |
| afResult = m_exynosCameraActivityControl->autoFocus(focusMode, m_autoFocusType, |
| m_flagStartFaceDetection, m_frameMetadata.number_of_faces); |
| if (afResult == true) |
| CLOGV("DEBUG(%s):autoFocus Success!!", __FUNCTION__); |
| else |
| CLOGV("DEBUG(%s):autoFocus Fail !!", __FUNCTION__); |
| } else { |
| CLOGV("DEBUG(%s):autoFocus canceled !!", __FUNCTION__); |
| } |
| |
| /* |
| * CAMERA_MSG_FOCUS only takes a bool. true for |
| * finished and false for failure. |
| * If cancelAutofocus() called, no callback. |
| */ |
| if ((m_autoFocusRunning == true) && |
| m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_FOCUS)) { |
| |
| if (m_notifyCb != NULL) { |
| int afFinalResult = (int)afResult; |
| #ifdef SAMSUNG_TN_FEATURE |
| /* if inactive detected, tell it */ |
| if (m_exynosCameraParameters->getSamsungCamera() == true && focusMode == FOCUS_MODE_CONTINUOUS_PICTURE) { |
| if (m_exynosCameraActivityControl->getCAFResult() == FOCUS_RESULT_CANCEL) { |
| afFinalResult = FOCUS_RESULT_CANCEL; |
| } |
| } |
| #endif |
| CLOGD("DEBUG(%s):CAMERA_MSG_FOCUS(%d) mode(%d)", __FUNCTION__, afFinalResult, focusMode); |
| m_autoFocusLock.unlock(); |
| m_notifyCb(CAMERA_MSG_FOCUS, afFinalResult, 0, m_callbackCookie); |
| m_autoFocusLock.lock(); |
| } else { |
| CLOGD("DEBUG(%s):m_notifyCb is NULL mode(%d)", __FUNCTION__, focusMode); |
| } |
| } else { |
| CLOGV("DEBUG(%s):autoFocus canceled, no callback !!", __FUNCTION__); |
| } |
| |
| autoFocusMgr->displayAFStatus(); |
| |
| m_autoFocusRunning = false; |
| |
| CLOGV("DEBUG(%s):exiting with no error", __FUNCTION__); |
| |
| #ifdef SAMSUNG_TN_FEATURE |
| if (focusMode == FOCUS_MODE_CONTINUOUS_PICTURE || focusMode == FOCUS_MODE_CONTINUOUS_VIDEO) { |
| bool prev_afInMotion = autoFocusMgr->getAfInMotionResult(); |
| bool afInMotion = false; |
| |
| autoFocusMgr->setAfInMotionResult(afInMotion); |
| |
| if (m_notifyCb != NULL && m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_FOCUS_MOVE) |
| && (prev_afInMotion != afInMotion)) { |
| CLOGD("DEBUG(%s):CAMERA_MSG_FOCUS_MOVE(%d) mode(%d)", |
| __FUNCTION__, afInMotion, m_exynosCameraParameters->getFocusMode()); |
| m_autoFocusLock.unlock(); |
| m_notifyCb(CAMERA_MSG_FOCUS_MOVE, afInMotion, 0, m_callbackCookie); |
| m_autoFocusLock.lock(); |
| } |
| } |
| #endif |
| done: |
| m_autoFocusLock.unlock(); |
| |
| CLOGI("DEBUG(%s):end", __FUNCTION__); |
| |
| return false; |
| } |
| |
| bool ExynosCamera::m_autoFocusContinousThreadFunc(void) |
| { |
| int ret = 0; |
| int index = 0; |
| uint32_t frameCnt = 0; |
| uint32_t count = 0; |
| |
| ret = m_autoFocusContinousQ.waitAndPopProcessQ(&frameCnt); |
| if (m_flagThreadStop == true) { |
| CLOGI("INFO(%s[%d]):m_flagThreadStop(%d)", __FUNCTION__, __LINE__, m_flagThreadStop); |
| return false; |
| } |
| if (ret < 0) { |
| /* TODO: We need to make timeout duration depends on FPS */ |
| if (ret == TIMED_OUT) { |
| CLOGW("WARN(%s):wait timeout", __FUNCTION__); |
| } else { |
| CLOGE("ERR(%s):wait and pop fail, ret(%d)", __FUNCTION__, ret); |
| /* TODO: doing exception handling */ |
| } |
| return true; |
| } |
| |
| count = m_autoFocusContinousQ.getSizeOfProcessQ(); |
| if( count >= MAX_FOCUSCONTINUS_THREADQ_SIZE ) { |
| for( uint32_t i = 0 ; i < count ; i++) { |
| m_autoFocusContinousQ.popProcessQ(&frameCnt); |
| } |
| CLOGD("DEBUG(%s[%d]):m_autoFocusContinousQ skipped QSize(%d) frame(%d)", __FUNCTION__, __LINE__, count, frameCnt); |
| } |
| |
| if(m_autoFocusRunning) { |
| return true; |
| } |
| |
| #ifdef SAMSUNG_TN_FEATURE |
| /* Continuous Auto-focus */ |
| if(m_exynosCameraParameters->getSamsungCamera() == true) { |
| if (m_exynosCameraParameters->getFocusMode() == FOCUS_MODE_CONTINUOUS_PICTURE) { |
| ExynosCameraActivityAutofocus *autoFocusMgr = m_exynosCameraActivityControl->getAutoFocusMgr(); |
| int afstatus = FOCUS_RESULT_FAIL; |
| static int afResult = FOCUS_RESULT_SUCCESS; |
| int prev_afstatus = afResult; |
| afstatus = m_exynosCameraActivityControl->getCAFResult(); |
| afResult = afstatus; |
| |
| if (afstatus == FOCUS_RESULT_FOCUSING && |
| (prev_afstatus == FOCUS_RESULT_FAIL || prev_afstatus == FOCUS_RESULT_SUCCESS)) { |
| afResult = FOCUS_RESULT_RESTART; |
| } |
| |
| if (m_notifyCb != NULL && m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_FOCUS) |
| && (prev_afstatus != afstatus)) { |
| CLOGD("DEBUG(%s):CAMERA_MSG_FOCUS(%d) mode(%d)", |
| __FUNCTION__, afResult, m_exynosCameraParameters->getFocusMode()); |
| m_notifyCb(CAMERA_MSG_FOCUS, afResult, 0, m_callbackCookie); |
| autoFocusMgr->displayAFStatus(); |
| } |
| } |
| } else { |
| if (m_exynosCameraParameters->getFocusMode() == FOCUS_MODE_CONTINUOUS_PICTURE |
| || m_exynosCameraParameters->getFocusMode() == FOCUS_MODE_CONTINUOUS_VIDEO) { |
| ExynosCameraActivityAutofocus *autoFocusMgr = m_exynosCameraActivityControl->getAutoFocusMgr(); |
| bool prev_afInMotion = autoFocusMgr->getAfInMotionResult(); |
| bool afInMotion = false; |
| switch (m_exynosCameraActivityControl->getCAFResult()) { |
| case FOCUS_RESULT_FAIL: // AA_AFSTATE_PASSIVE_UNFOCUSED |
| case FOCUS_RESULT_SUCCESS: // AA_AFSTATE_PASSIVE_FOCUSED |
| afInMotion = false; |
| break; |
| case FOCUS_RESULT_FOCUSING: // AA_AFSTATE_PASSIVE_SCAN, AA_AFSTATE_ACTIVE_SCAN |
| afInMotion = true; |
| break; |
| } |
| autoFocusMgr->setAfInMotionResult(afInMotion); |
| |
| if (m_notifyCb != NULL && m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_FOCUS_MOVE) |
| && (prev_afInMotion != afInMotion)) { |
| m_notifyCb(CAMERA_MSG_FOCUS_MOVE, afInMotion, 0, m_callbackCookie); |
| } |
| } |
| } |
| #endif |
| return true; |
| } |
| |
| status_t ExynosCamera::dump(__unused int fd) const |
| { |
| CLOGI("INFO(%s[%d]):", __FUNCTION__, __LINE__); |
| |
| return NO_ERROR; |
| } |
| |
| void ExynosCamera::dump() |
| { |
| CLOGI("INFO(%s[%d]):", __FUNCTION__, __LINE__); |
| |
| m_printExynosCameraInfo(__FUNCTION__); |
| |
| if (m_previewFrameFactory != NULL) |
| m_previewFrameFactory->dump(); |
| |
| if (m_bayerBufferMgr != NULL) |
| m_bayerBufferMgr->dump(); |
| #ifdef SAMSUNG_DNG |
| if (m_fliteBufferMgr != NULL) |
| m_fliteBufferMgr->dump(); |
| #endif |
| if (m_3aaBufferMgr != NULL) |
| m_3aaBufferMgr->dump(); |
| if (m_ispBufferMgr != NULL) |
| m_ispBufferMgr->dump(); |
| if (m_hwDisBufferMgr != NULL) |
| m_hwDisBufferMgr->dump(); |
| if (m_scpBufferMgr != NULL) |
| m_scpBufferMgr->dump(); |
| |
| if (m_ispReprocessingBufferMgr != NULL) |
| m_ispReprocessingBufferMgr->dump(); |
| if (m_sccReprocessingBufferMgr != NULL) |
| m_sccReprocessingBufferMgr->dump(); |
| if (m_sccBufferMgr != NULL) |
| m_sccBufferMgr->dump(); |
| if (m_gscBufferMgr != NULL) |
| m_gscBufferMgr->dump(); |
| |
| #ifdef SUPPORT_SW_VDIS |
| if (m_swVDIS_BufferMgr != NULL) |
| m_swVDIS_BufferMgr->dump(); |
| #endif /*SUPPORT_SW_VDIS*/ |
| return; |
| } |
| |
| status_t ExynosCamera::m_getBufferManager(uint32_t pipeId, ExynosCameraBufferManager **bufMgr, uint32_t direction) |
| { |
| status_t ret = NO_ERROR; |
| ExynosCameraBufferManager **bufMgrList[2] = {NULL}; |
| *bufMgr = NULL; |
| int internalPipeId = pipeId; |
| |
| /* |
| * front / back is different up to scenario(3AA OTF/M2M, etc) |
| * so, we don't need to distinguish front / back camera. |
| * but. reprocessing must handle the separated operation |
| */ |
| if (pipeId < PIPE_FLITE_REPROCESSING) |
| internalPipeId = INDEX(pipeId); |
| |
| switch (internalPipeId) { |
| case PIPE_FLITE: |
| #ifdef SAMSUNG_DNG |
| if(m_exynosCameraParameters->getDNGCaptureModeOn()) { |
| bufMgrList[0] = NULL; |
| bufMgrList[1] = &m_fliteBufferMgr; |
| } else |
| #endif |
| { |
| bufMgrList[0] = NULL; |
| bufMgrList[1] = &m_bayerBufferMgr; |
| } |
| break; |
| case PIPE_3AA_ISP: |
| bufMgrList[0] = &m_3aaBufferMgr; |
| bufMgrList[1] = &m_ispBufferMgr; |
| break; |
| case PIPE_3AC: |
| bufMgrList[0] = NULL; |
| bufMgrList[1] = &m_bayerBufferMgr; |
| break; |
| case PIPE_3AA: |
| if (m_exynosCameraParameters->getDualMode() == true && getCameraId() == CAMERA_ID_FRONT) { |
| bufMgrList[0] = &m_bayerBufferMgr; |
| bufMgrList[1] = &m_sccBufferMgr; |
| } else { |
| bufMgrList[0] = &m_3aaBufferMgr; |
| |
| if (m_exynosCameraParameters->is3aaIspOtf() == true) { |
| bufMgrList[1] = &m_hwDisBufferMgr; |
| } else { |
| bufMgrList[1] = &m_ispBufferMgr; |
| } |
| } |
| break; |
| case PIPE_ISP: |
| bufMgrList[0] = &m_ispBufferMgr; |
| |
| if (m_exynosCameraParameters->getTpuEnabledMode() == true) |
| bufMgrList[1] = &m_hwDisBufferMgr; |
| else |
| bufMgrList[1] = &m_scpBufferMgr; |
| break; |
| case PIPE_DIS: |
| bufMgrList[0] = &m_hwDisBufferMgr; |
| bufMgrList[1] = &m_scpBufferMgr; |
| break; |
| case PIPE_ISPC: |
| case PIPE_SCC: |
| bufMgrList[0] = NULL; |
| bufMgrList[1] = &m_sccBufferMgr; |
| break; |
| case PIPE_SCP: |
| bufMgrList[0] = NULL; |
| bufMgrList[1] = &m_scpBufferMgr; |
| break; |
| case PIPE_GSC: |
| if (m_exynosCameraParameters->getDualMode() == true && getCameraId() == CAMERA_ID_FRONT) |
| bufMgrList[0] = &m_sccBufferMgr; |
| else |
| bufMgrList[0] = &m_scpBufferMgr; |
| bufMgrList[1] = &m_scpBufferMgr; |
| break; |
| case PIPE_GSC_VIDEO: |
| bufMgrList[0] = &m_sccBufferMgr; |
| bufMgrList[1] = &m_postPictureGscBufferMgr; |
| break; |
| case PIPE_GSC_PICTURE: |
| bufMgrList[0] = &m_sccBufferMgr; |
| bufMgrList[1] = &m_gscBufferMgr; |
| break; |
| case PIPE_3AA_REPROCESSING: |
| bufMgrList[0] = &m_bayerBufferMgr; |
| if (m_exynosCameraParameters->getDualMode() == false) |
| bufMgrList[1] = &m_ispReprocessingBufferMgr; |
| else |
| bufMgrList[1] = &m_sccReprocessingBufferMgr; |
| break; |
| case PIPE_ISP_REPROCESSING: |
| bufMgrList[0] = &m_ispReprocessingBufferMgr; |
| bufMgrList[1] = &m_sccReprocessingBufferMgr; |
| break; |
| case PIPE_ISPC_REPROCESSING: |
| case PIPE_SCC_REPROCESSING: |
| bufMgrList[0] = NULL; |
| bufMgrList[1] = &m_sccReprocessingBufferMgr; |
| break; |
| case PIPE_GSC_REPROCESSING: |
| bufMgrList[0] = &m_sccReprocessingBufferMgr; |
| bufMgrList[1] = &m_gscBufferMgr; |
| break; |
| case PIPE_GSC_REPROCESSING2: |
| #ifdef SAMSUNG_DEBLUR |
| if (getUseDeblurCaptureOn()) { |
| bufMgrList[0] = &m_gscBufferMgr; |
| } else |
| #endif |
| { |
| bufMgrList[0] = &m_sccReprocessingBufferMgr; |
| } |
| bufMgrList[1] = &m_postPictureGscBufferMgr; |
| break; |
| case PIPE_GSC_REPROCESSING3: |
| bufMgrList[0] = &m_postPictureGscBufferMgr; |
| bufMgrList[1] = &m_thumbnailGscBufferMgr; |
| break; |
| default: |
| CLOGE("ERR(%s[%d]): Unknown pipeId(%d)", __FUNCTION__, __LINE__, pipeId); |
| bufMgrList[0] = NULL; |
| bufMgrList[1] = NULL; |
| ret = BAD_VALUE; |
| break; |
| } |
| |
| if (bufMgrList[direction] != NULL) |
| *bufMgr = *bufMgrList[direction]; |
| |
| return ret; |
| } |
| |
| uint32_t ExynosCamera::m_getBayerPipeId(void) |
| { |
| uint32_t pipeId = 0; |
| |
| if (m_exynosCameraParameters->getUsePureBayerReprocessing() == true) { |
| pipeId = PIPE_FLITE; |
| } else { |
| pipeId = PIPE_3AA; |
| } |
| |
| return pipeId; |
| } |
| |
| void ExynosCamera::m_debugFpsCheck(__unused uint32_t pipeId) |
| { |
| #ifdef FPS_CHECK |
| uint32_t id = pipeId % DEBUG_MAX_PIPE_NUM; |
| |
| m_debugFpsCount[id]++; |
| if (m_debugFpsCount[id] == 1) { |
| m_debugFpsTimer[id].start(); |
| } |
| if (m_debugFpsCount[id] == 31) { |
| m_debugFpsTimer[id].stop(); |
| long long durationTime = m_debugFpsTimer[id].durationMsecs(); |
| CLOGI("INFO(%s[%d]): FPS_CHECK(id:%d), duration %lld / 30 = %lld ms. %lld fps", |
| __FUNCTION__, __LINE__, pipeId, durationTime, durationTime / 30, 1000 / (durationTime / 30)); |
| m_debugFpsCount[id] = 0; |
| } |
| #endif |
| } |
| |
| status_t ExynosCamera::m_convertingStreamToShotExt(ExynosCameraBuffer *buffer, struct camera2_node_output *outputInfo) |
| { |
| /* TODO: HACK: Will be removed, this is driver's job */ |
| status_t ret = NO_ERROR; |
| int bayerFrameCount = 0; |
| camera2_shot_ext *shot_ext = NULL; |
| camera2_stream *shot_stream = NULL; |
| |
| shot_stream = (struct camera2_stream *)buffer->addr[buffer->planeCount-1]; |
| bayerFrameCount = shot_stream->fcount; |
| outputInfo->cropRegion[0] = shot_stream->output_crop_region[0]; |
| outputInfo->cropRegion[1] = shot_stream->output_crop_region[1]; |
| outputInfo->cropRegion[2] = shot_stream->output_crop_region[2]; |
| outputInfo->cropRegion[3] = shot_stream->output_crop_region[3]; |
| |
| memset(buffer->addr[buffer->planeCount-1], 0x0, sizeof(struct camera2_shot_ext)); |
| |
| shot_ext = (struct camera2_shot_ext *)buffer->addr[buffer->planeCount-1]; |
| shot_ext->shot.dm.request.frameCount = bayerFrameCount; |
| |
| return ret; |
| } |
| |
| #ifdef SAMSUNG_DNG |
| unsigned int ExynosCamera::getDNGFcount() |
| { |
| unsigned int shotFcount = 0; |
| ExynosCameraActivitySpecialCapture *m_sCaptureMgr = NULL; |
| ExynosCameraActivityFlash *m_flashMgr = m_exynosCameraActivityControl->getFlashMgr(); |
| m_sCaptureMgr = m_exynosCameraActivityControl->getSpecialCaptureMgr(); |
| |
| CLOGV("[DNG](%s[%d]):getOISCaptureModeOn(%d) getOISCaptureFcount(%d)", |
| __FUNCTION__, __LINE__, m_exynosCameraParameters->getOISCaptureModeOn(), m_sCaptureMgr->getOISCaptureFcount()); |
| |
| if (m_sCaptureMgr->getOISCaptureFcount() > 0) { |
| shotFcount = m_sCaptureMgr->getOISCaptureFcount() + OISCAPTURE_DELAY; |
| } else if (m_flashMgr->getNeedCaptureFlash() == true && m_flashMgr->getShotFcount()) { |
| shotFcount = m_flashMgr->getShotFcount() + 1; |
| } else if (m_exynosCameraParameters->getCaptureExposureTime() > CAMERA_PREVIEW_EXPOSURE_TIME_LIMIT) { |
| shotFcount = m_dngFrameNumberForManualExposure; |
| } |
| |
| return shotFcount; |
| } |
| |
| bool ExynosCamera::m_DNGCaptureThreadFunc(void) |
| { |
| ExynosCameraBuffer dngBuffer[3]; |
| ExynosCameraBuffer *saveDngBuffer[3]; |
| ExynosCameraBuffer *tempDngBuffer; |
| int loop = false; |
| int ret = 0; |
| int count; |
| int saveCount; |
| unsigned int fliteFcount = 0; |
| camera2_shot_ext *shot_ext = NULL; |
| ExynosRect srcRect, dstRect; |
| |
| m_exynosCameraParameters->getPictureBayerCropSize(&srcRect, &dstRect); |
| |
| for (int i = 0; i < 3; i++) { |
| dngBuffer[i].index = -2; |
| saveDngBuffer[i] = &dngBuffer[i]; |
| } |
| saveCount = 0; |
| tempDngBuffer = NULL; |
| |
| CLOGD("[DNG](%s[%d]):-- IN --", __FUNCTION__, __LINE__); |
| |
| DNG_RETRY: |
| if (m_exynosCameraParameters->getCaptureExposureTime() != 0 && m_stopLongExposure) { |
| CLOGD("[DNG](%s[%d]):flite emergency stop", __FUNCTION__, __LINE__); |
| m_longExposureEnds = true; |
| m_searchDNGFrame = false; |
| m_pictureEnabled = false; |
| CLOGD("[DNG](%s[%d]):request flite stop", __FUNCTION__, __LINE__); |
| m_previewFrameFactory->setRequestFLITE(false); |
| goto CLEAN; |
| } |
| tempDngBuffer = saveDngBuffer[saveCount]; |
| |
| /* wait flite */ |
| CLOGV("INFO(%s[%d]):wait flite output", __FUNCTION__, __LINE__); |
| ret = m_dngCaptureQ->waitAndPopProcessQ(tempDngBuffer); |
| CLOGD("[DNG](%s[%d]):flite output done pipe", __FUNCTION__, __LINE__); |
| if (ret < 0) { |
| CLOGE("ERR(%s)(%d):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| /* TODO: doing exception handling */ |
| goto CLEAN; |
| } |
| |
| saveCount++; |
| |
| /* Rawdump capture is available in pure bayer only */ |
| shot_ext = (camera2_shot_ext *)(tempDngBuffer->addr[1]); |
| if (shot_ext != NULL) |
| fliteFcount = shot_ext->shot.dm.request.frameCount; |
| else |
| ALOGE("ERR(%s[%d]):fliteReprocessingBuffer is null", __FUNCTION__, __LINE__); |
| |
| if (fliteFcount == 0) { |
| ALOGE("ERR(%s[%d]):fliteFcount is null", __FUNCTION__, __LINE__); |
| goto DNG_RETRY; |
| } |
| |
| if (m_exynosCameraParameters->getCaptureExposureTime() != 0 && |
| m_exynosCameraParameters->getCheckMultiFrame() && |
| getDNGFcount() == 0) { |
| if (saveCount >= 3) { |
| shot_ext = (camera2_shot_ext *)(saveDngBuffer[0]->addr[1]); |
| if (shot_ext->shot.dm.request.frameCount != 0) { |
| ret = m_putBuffers(m_fliteBufferMgr, saveDngBuffer[0]->index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_putBuffers(%d) fail", __FUNCTION__, __LINE__, saveDngBuffer[0]->index); |
| goto CLEAN; |
| } |
| } |
| tempDngBuffer = saveDngBuffer[0]; |
| saveDngBuffer[0] = saveDngBuffer[1]; |
| saveDngBuffer[1] = saveDngBuffer[2]; |
| saveDngBuffer[2] = tempDngBuffer; |
| saveDngBuffer[2]->index = -2; |
| saveCount--; |
| } |
| goto DNG_RETRY; |
| } else if (m_exynosCameraParameters->getCaptureExposureTime() != 0 && |
| m_exynosCameraParameters->getCheckMultiFrame() && |
| getDNGFcount() != 0 && fliteFcount < getDNGFcount()) { |
| for (count = 0; count < saveCount; count++) { |
| shot_ext = (camera2_shot_ext *)(saveDngBuffer[count]->addr[1]); |
| if (shot_ext->shot.dm.request.frameCount != 0) { |
| ret = m_putBuffers(m_fliteBufferMgr, saveDngBuffer[count]->index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_putBuffers(%d) fail", __FUNCTION__, __LINE__, saveDngBuffer[count]->index); |
| goto CLEAN; |
| } |
| } |
| saveDngBuffer[count]->index = -2; |
| } |
| saveCount = 0; |
| goto DNG_RETRY; |
| } else if (m_exynosCameraParameters->getCaptureExposureTime() != 0 && |
| m_exynosCameraParameters->getCheckMultiFrame() && |
| getDNGFcount() != 0 && fliteFcount >= getDNGFcount()) { |
| for (count = 0; count < saveCount; count++) { |
| shot_ext = (camera2_shot_ext *)(saveDngBuffer[count]->addr[1]); |
| if (shot_ext->shot.dm.request.frameCount >= getDNGFcount()) { |
| break; |
| } else { |
| if (shot_ext->shot.dm.request.frameCount != 0) { |
| ret = m_putBuffers(m_fliteBufferMgr, saveDngBuffer[count]->index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_putBuffers(%d) fail", __FUNCTION__, __LINE__, saveDngBuffer[count]->index); |
| goto CLEAN; |
| } |
| } |
| saveDngBuffer[count]->index = -2; |
| } |
| } |
| saveCount = 0; |
| for (int i = 0; i < 3; i++) { |
| if (saveDngBuffer[i]->index != -2) { |
| saveCount++; |
| } |
| } |
| if (saveCount == 2 && saveDngBuffer[0]->index == -2) { |
| tempDngBuffer = saveDngBuffer[0]; |
| saveDngBuffer[0] = saveDngBuffer[1]; |
| saveDngBuffer[1] = saveDngBuffer[2]; |
| saveDngBuffer[2] = tempDngBuffer; |
| } else if (saveCount == 1 && saveDngBuffer[0]->index == -2) { |
| if (saveDngBuffer[1]->index == -2) { |
| tempDngBuffer = saveDngBuffer[0]; |
| saveDngBuffer[0] = saveDngBuffer[2]; |
| saveDngBuffer[2] = tempDngBuffer; |
| } else { |
| tempDngBuffer = saveDngBuffer[0]; |
| saveDngBuffer[0] = saveDngBuffer[1]; |
| saveDngBuffer[1] = tempDngBuffer; |
| } |
| } |
| if (m_dngLongExposureRemainCount <= 0) { |
| for (count = 1; count < saveCount; count++) { |
| if (saveDngBuffer[count]->index != -2) { |
| shot_ext = (camera2_shot_ext *)(saveDngBuffer[count]->addr[1]); |
| if (shot_ext->shot.dm.request.frameCount != 0) { |
| ret = m_putBuffers(m_fliteBufferMgr, saveDngBuffer[count]->index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_putBuffers(%d) fail", __FUNCTION__, __LINE__, saveDngBuffer[count]->index); |
| goto CLEAN; |
| } |
| } |
| saveDngBuffer[count]->index = -2; |
| } |
| } |
| saveCount = 1; |
| } |
| } |
| |
| if (m_dngLongExposureRemainCount > 0 && saveDngBuffer[2]->index != -2) { |
| ret = addBayerBuffer(saveDngBuffer[2], saveDngBuffer[0], &dstRect); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):addBayerBuffer() fail", __FUNCTION__, __LINE__); |
| } |
| |
| ret = m_putBuffers(m_fliteBufferMgr, saveDngBuffer[2]->index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_putBuffers(%d) fail", __FUNCTION__, __LINE__, saveDngBuffer[2]->index); |
| goto CLEAN; |
| } |
| saveDngBuffer[2]->index = -2; |
| saveCount--; |
| m_dngLongExposureRemainCount--; |
| } |
| |
| if (m_dngLongExposureRemainCount > 0 && saveDngBuffer[1]->index != -2) { |
| ret = addBayerBuffer(saveDngBuffer[1], saveDngBuffer[0], &dstRect); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):addBayerBuffer() fail", __FUNCTION__, __LINE__); |
| } |
| |
| ret = m_putBuffers(m_fliteBufferMgr, saveDngBuffer[1]->index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_putBuffers(%d) fail", __FUNCTION__, __LINE__, saveDngBuffer[1]->index); |
| goto CLEAN; |
| } |
| saveDngBuffer[1]->index = -2; |
| saveCount--; |
| m_dngLongExposureRemainCount--; |
| if (m_dngLongExposureRemainCount > 0) { |
| goto DNG_RETRY; |
| } |
| } else if (m_dngLongExposureRemainCount > 0 && saveDngBuffer[1]->index == -2) { |
| goto DNG_RETRY; |
| } |
| |
| #ifdef CAMERA_ADD_BAYER_ENABLE |
| if (mIonClient >= 0) |
| ion_sync_fd(mIonClient, saveDngBuffer[0]->fd[0]); |
| #endif |
| |
| m_longExposureEnds = true; |
| |
| CLOGD("[DNG](%s[%d]):frame count (%d)", __FUNCTION__, __LINE__, fliteFcount); |
| |
| #if 0 |
| int sensorMaxW, sensorMaxH; |
| int sensorMarginW, sensorMarginH; |
| bool bRet; |
| char filePath[70]; |
| |
| memset(filePath, 0, sizeof(filePath)); |
| snprintf(filePath, sizeof(filePath), "/data/media/0/fliteCapture%d_%d.dng", |
| m_exynosCameraParameters->getCameraId(), fliteFcount); |
| /* Pure Bayer Buffer Size == MaxPictureSize + Sensor Margin == Max Sensor Size */ |
| m_exynosCameraParameters->getMaxSensorSize(&sensorMaxW, &sensorMaxH); |
| |
| CLOGD("[DNG](%s[%d]):Raw frame count (%d)", __FUNCTION__, __LINE__, fliteFcount); |
| |
| CLOGD("[DNG](%s[%d]):Raw Dump start (%s)", __FUNCTION__, __LINE__, filePath); |
| |
| bRet = dumpToFile((char *)filePath, |
| dngBuffer.addr[0], |
| dngBuffer.size[0]); |
| if (bRet != true) |
| ALOGE("couldn't make a raw file", __FUNCTION__, __LINE__); |
| CLOGD("[DNG](%s[%d]):Raw Dump end (%s)", __FUNCTION__, __LINE__, filePath); |
| #endif |
| |
| if (m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_RAW_IMAGE)) { |
| // Make Dng format |
| m_dngCreator.makeDng(m_exynosCameraParameters, saveDngBuffer[0]->addr[0], &saveDngBuffer[0]->size[0]); |
| |
| // Check DNG save path |
| char default_path[20]; |
| memset(default_path, 0, sizeof(default_path)); |
| strncpy(default_path, CAMERA_SAVE_PATH_PHONE, sizeof(default_path)-1); |
| m_CheckCameraSavingPath(default_path, |
| m_exynosCameraParameters->getDngFilePath(), |
| m_dngSavePath, sizeof(m_dngSavePath)); |
| |
| CLOGD("DNG(%s[%d]): RAW callback", __FUNCTION__, __LINE__); |
| // Make Callback Buffer |
| camera_memory_t *rawCallbackHeap = NULL; |
| rawCallbackHeap = m_getDngCallbackHeap(saveDngBuffer[0]); |
| if (!rawCallbackHeap || rawCallbackHeap->data == MAP_FAILED) { |
| CLOGE("ERR(%s[%d]):m_getMemoryCb(%d) fail", __FUNCTION__, __LINE__, saveDngBuffer[0]->size[0]); |
| goto CLEAN; |
| } |
| |
| if (!m_cancelPicture) { |
| setBit(&m_callbackState, CALLBACK_STATE_RAW_IMAGE, true); |
| m_dataCb(CAMERA_MSG_RAW_IMAGE, rawCallbackHeap, 0, NULL, m_callbackCookie); |
| clearBit(&m_callbackState, CALLBACK_STATE_RAW_IMAGE, true); |
| } |
| rawCallbackHeap->release(rawCallbackHeap); |
| } |
| |
| CLEAN: |
| for (count = 0; count < 3; count++) { |
| if (saveDngBuffer[count]->index != -2) { |
| ret = m_putBuffers(m_fliteBufferMgr, saveDngBuffer[count]->index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_putBuffers(%d) fail", __FUNCTION__, __LINE__, saveDngBuffer[count]->index); |
| } |
| } |
| } |
| |
| return loop; |
| } |
| |
| camera_memory_t *ExynosCamera::m_getDngCallbackHeap(ExynosCameraBuffer *dngBuf) |
| { |
| camera_memory_t *dngCallbackHeap = NULL; |
| int dngSaveLocation = m_exynosCameraParameters->getDngSaveLocation(); |
| |
| CLOGI("INFO(%s[%d]):", __FUNCTION__, __LINE__); |
| |
| if (dngSaveLocation == BURST_SAVE_CALLBACK) { |
| CLOGD("DEBUG(%s[%d]):burst callback : size (%d)", __FUNCTION__, __LINE__, dngBuf->size[0]); |
| |
| dngCallbackHeap = m_getMemoryCb(dngBuf->fd[0], dngBuf->size[0], 1, m_callbackCookie); |
| if (!dngCallbackHeap || dngCallbackHeap->data == MAP_FAILED) { |
| CLOGE("ERR(%s[%d]):m_getMemoryCb(%d) fail", __FUNCTION__, __LINE__, dngBuf->size[0]); |
| goto done; |
| } |
| if (dngBuf->fd[0] < 0) |
| memcpy(dngCallbackHeap->data, dngBuf->addr[0], dngBuf->size[0]); |
| } else { |
| char filePath[CAMERA_FILE_PATH_SIZE]; |
| time_t rawtime; |
| struct tm *timeinfo; |
| |
| // Get current local time |
| time(&rawtime); |
| timeinfo = localtime(&rawtime); |
| strftime(m_dngTime, 20, "%Y%m%d_%H%M%S", timeinfo); |
| |
| // Get Full Path Name (Path + FileName) |
| memset(filePath, 0, sizeof(filePath)); |
| snprintf(filePath, sizeof(filePath), "%s%s_hal.dng", m_dngSavePath, m_dngTime); |
| CLOGD("DEBUG(%s[%d]):burst callback : size (%d), filePath(%s)", |
| __FUNCTION__, __LINE__, dngBuf->size[0], filePath); |
| |
| if(m_FileSaveFunc(filePath, dngBuf) == false) { |
| CLOGE("ERR(%s[%d]): FILE save ERROR", __FUNCTION__, __LINE__); |
| goto done; |
| } |
| |
| dngCallbackHeap = m_getMemoryCb(-1, sizeof(filePath), 1, m_callbackCookie); |
| if (!dngCallbackHeap || dngCallbackHeap->data == MAP_FAILED) { |
| CLOGE("ERR(%s[%d]):m_getMemoryCb(%s) fail", __FUNCTION__, __LINE__, filePath); |
| goto done; |
| } |
| |
| memcpy(dngCallbackHeap->data, filePath, sizeof(filePath)); |
| } |
| |
| done: |
| |
| if (dngCallbackHeap == NULL || dngCallbackHeap->data == MAP_FAILED) { |
| if (dngCallbackHeap) { |
| dngCallbackHeap->release(dngCallbackHeap); |
| dngCallbackHeap = NULL; |
| } |
| |
| m_notifyCb(CAMERA_MSG_ERROR, -1, 0, m_callbackCookie); |
| } |
| |
| CLOGD("INFO(%s[%d]):making callback buffer done", __FUNCTION__, __LINE__); |
| |
| return dngCallbackHeap; |
| } |
| #endif |
| |
| #ifdef RAWDUMP_CAPTURE |
| bool ExynosCamera::m_RawCaptureDumpThreadFunc(void) |
| { |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| CLOGI("DEBUG(%s[%d]):", __FUNCTION__, __LINE__); |
| |
| int ret = 0; |
| int sensorMaxW, sensorMaxH; |
| int sensorMarginW, sensorMarginH; |
| bool bRet; |
| char filePath[70]; |
| ExynosCameraBufferManager *bufferMgr = NULL; |
| int bayerPipeId = 0; |
| ExynosCameraBuffer bayerBuffer; |
| ExynosCameraFrame *newFrame = NULL; |
| ExynosCameraFrame *inListFrame = NULL; |
| unsigned int fliteFcount = 0; |
| |
| ret = m_RawCaptureDumpQ->waitAndPopProcessQ(&newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| // TODO: doing exception handling |
| goto CLEAN; |
| } |
| if (newFrame == NULL) { |
| CLOGE("ERR(%s[%d]):newFrame is NULL", __FUNCTION__, __LINE__); |
| goto CLEAN; |
| } |
| |
| bayerPipeId = newFrame->getFirstEntity()->getPipeId(); |
| ret = newFrame->getDstBuffer(bayerPipeId, &bayerBuffer); |
| ret = m_getBufferManager(bayerPipeId, &bufferMgr, DST_BUFFER_DIRECTION); |
| |
| /* Rawdump capture is available in pure bayer only */ |
| if (m_exynosCameraParameters->getUsePureBayerReprocessing() == true) { |
| camera2_shot_ext *shot_ext = NULL; |
| shot_ext = (camera2_shot_ext *)(bayerBuffer.addr[1]); |
| if (shot_ext != NULL) |
| fliteFcount = shot_ext->shot.dm.request.frameCount; |
| else |
| ALOGE("ERR(%s[%d]):fliteReprocessingBuffer is null", __FUNCTION__, __LINE__); |
| } else { |
| camera2_stream *shot_stream = NULL; |
| shot_stream = (camera2_stream *)(bayerBuffer.addr[1]); |
| if (shot_stream != NULL) |
| fliteFcount = shot_stream->fcount; |
| else |
| ALOGE("ERR(%s[%d]):fliteReprocessingBuffer is null", __FUNCTION__, __LINE__); |
| } |
| |
| memset(filePath, 0, sizeof(filePath)); |
| snprintf(filePath, sizeof(filePath), "/data/media/0/RawCapture%d_%d.raw", |
| m_exynosCameraParameters->getCameraId(), fliteFcount); |
| /* Pure Bayer Buffer Size == MaxPictureSize + Sensor Margin == Max Sensor Size */ |
| m_exynosCameraParameters->getMaxSensorSize(&sensorMaxW, &sensorMaxH); |
| |
| CLOGD("INFO(%s[%d]):Raw Dump start (%s)", __FUNCTION__, __LINE__, filePath); |
| |
| bRet = dumpToFile((char *)filePath, |
| bayerBuffer.addr[0], |
| sensorMaxW * sensorMaxH * 2); |
| if (bRet != true) |
| ALOGE("couldn't make a raw file", __FUNCTION__, __LINE__); |
| |
| ret = bufferMgr->putBuffer(bayerBuffer.index, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL); |
| if (ret < 0) { |
| ALOGE("ERR(%s[%d]):putIndex is %d", __FUNCTION__, __LINE__, bayerBuffer.index); |
| bufferMgr->printBufferState(); |
| bufferMgr->printBufferQState(); |
| } |
| |
| CLEAN: |
| |
| if (newFrame != NULL) { |
| newFrame->frameUnlock(); |
| |
| ret = m_searchFrameFromList(&m_processList, newFrame->getFrameCount(), &inListFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):searchFrameFromList fail", __FUNCTION__, __LINE__); |
| } else { |
| if (inListFrame == NULL) { |
| CLOGD("DEBUG(%s[%d]): Selected frame(%d) complete, Delete", |
| __FUNCTION__, __LINE__, newFrame->getFrameCount()); |
| newFrame->decRef(); |
| m_frameMgr->deleteFrame(newFrame); |
| } |
| newFrame = NULL; |
| } |
| } |
| |
| return ret; |
| } |
| #endif |
| |
| status_t ExynosCamera::m_getBayerBuffer(uint32_t pipeId, ExynosCameraBuffer *buffer, camera2_shot_ext *updateDmShot) |
| { |
| status_t ret = NO_ERROR; |
| bool isSrc = false; |
| int retryCount = 30; /* 200ms x 30 */ |
| camera2_shot_ext *shot_ext = NULL; |
| camera2_stream *shot_stream = NULL; |
| ExynosCameraFrame *inListFrame = NULL; |
| ExynosCameraFrame *bayerFrame = NULL; |
| ExynosCameraBuffer *saveBuffer = NULL; |
| ExynosCameraBuffer tempBuffer; |
| ExynosRect srcRect, dstRect; |
| |
| #ifdef LLS_REPROCESSING |
| unsigned int fliteFcount = 0; |
| #endif |
| int trycount = 0; |
| m_exynosCameraParameters->getPictureBayerCropSize(&srcRect, &dstRect); |
| |
| BAYER_RETRY: |
| #ifdef ONE_SECOND_BURST_CAPTURE |
| if (m_exynosCameraParameters->getCaptureExposureTime() != 0 && |
| m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_ONE_SECOND_BURST) { |
| CLOGD("DEBUG(%s[%d]): manual exposure mode. Stop one second burst.", __FUNCTION__, __LINE__); |
| m_stopLongExposure = true; |
| m_jpegCallbackCounter.clearCount(); |
| m_stopBurstShot = true; |
| } |
| #endif |
| |
| if (m_exynosCameraParameters->getCaptureExposureTime() != 0 && m_stopLongExposure) { |
| CLOGD("DEBUG(%s[%d]): Emergency stop", __FUNCTION__, __LINE__); |
| m_reprocessingCounter.clearCount(); |
| m_pictureEnabled = false; |
| goto CLEAN; |
| } |
| |
| #ifdef OIS_CAPTURE |
| if (m_exynosCameraParameters->getOISCaptureModeOn() == true) { |
| retryCount = 7; |
| #ifdef SAMSUNG_LLS_DEBLUR |
| if (m_exynosCameraParameters->getLDCaptureMode() > 0 |
| && m_exynosCameraParameters->getLDCaptureMode() < MULTI_SHOT_MODE_MULTI3) { |
| m_captureSelector->setWaitTimeOISCapture(70000000); |
| } else |
| #endif |
| { |
| m_captureSelector->setWaitTimeOISCapture(130000000); |
| } |
| } |
| #endif |
| |
| m_captureSelector->setWaitTime(200000000); |
| #ifdef RAWDUMP_CAPTURE |
| for (int i = 0; i < 2; i++) { |
| bayerFrame = m_captureSelector->selectFrames(m_reprocessingCounter.getCount(), pipeId, isSrc, retryCount); |
| |
| if(i == 0) { |
| m_RawCaptureDumpQ->pushProcessQ(&bayerFrame); |
| } else if (i == 1) { |
| m_exynosCameraParameters->setRawCaptureModeOn(false); |
| } |
| } |
| #else |
| #ifdef SAMSUNG_QUICKSHOT |
| if (m_exynosCameraParameters->getQuickShot() && m_quickShotStart) { |
| for (int i = 0; i < FRAME_SKIP_COUNT_QUICK_SHOT; i++) { |
| bayerFrame = m_captureSelector->selectFrames(m_reprocessingCounter.getCount(), pipeId, isSrc, retryCount); |
| } |
| } else |
| #endif |
| { |
| bayerFrame = m_captureSelector->selectFrames(m_reprocessingCounter.getCount(), pipeId, isSrc, retryCount); |
| } |
| #ifdef SAMSUNG_QUICKSHOT |
| m_quickShotStart = false; |
| #endif |
| #endif |
| if (bayerFrame == NULL) { |
| CLOGE("ERR(%s[%d]):bayerFrame is NULL", __FUNCTION__, __LINE__); |
| ret = INVALID_OPERATION; |
| goto CLEAN; |
| } |
| |
| #ifdef LLS_REPROCESSING |
| m_exynosCameraParameters->setSetfileYuvRange(); |
| #endif |
| |
| if (pipeId == PIPE_3AA) { |
| ret = bayerFrame->getDstBuffer(pipeId, buffer, m_previewFrameFactory->getNodeType(pipeId)); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): getDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId, ret); |
| goto CLEAN; |
| } |
| } else if (pipeId == PIPE_FLITE) { |
| ret = bayerFrame->getDstBuffer(pipeId, buffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): getDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId, ret); |
| goto CLEAN; |
| } |
| } |
| |
| if (m_exynosCameraParameters->getReprocessingBayerMode() == REPROCESSING_BAYER_MODE_PURE_ALWAYS_ON || |
| m_exynosCameraParameters->getReprocessingBayerMode() == REPROCESSING_BAYER_MODE_PURE_DYNAMIC) { |
| shot_ext = (struct camera2_shot_ext *)buffer->addr[1]; |
| CLOGD("DEBUG(%s[%d]): Selected frame count(hal : %d / driver : %d)", __FUNCTION__, __LINE__, |
| bayerFrame->getFrameCount(), shot_ext->shot.dm.request.frameCount); |
| } else if (m_exynosCameraParameters->getReprocessingBayerMode() == REPROCESSING_BAYER_MODE_DIRTY_ALWAYS_ON || |
| m_exynosCameraParameters->getReprocessingBayerMode() == REPROCESSING_BAYER_MODE_DIRTY_DYNAMIC) { |
| if (updateDmShot == NULL) { |
| CLOGE("ERR(%s[%d]): updateDmShot is NULL", __FUNCTION__, __LINE__); |
| goto CLEAN; |
| } |
| |
| retryCount = 12; /* 80ms * 12 */ |
| while (retryCount > 0) { |
| if (bayerFrame->getMetaDataEnable() == false) { |
| CLOGD("DEBUG(%s[%d]): Waiting for update jpeg metadata failed (%d), retryCount(%d)", __FUNCTION__, __LINE__, ret, retryCount); |
| } else { |
| break; |
| } |
| retryCount--; |
| usleep(DM_WAITING_TIME); |
| } |
| |
| /* update meta like pure bayer */ |
| bayerFrame->getUserDynamicMeta(updateDmShot); |
| bayerFrame->getDynamicMeta(updateDmShot); |
| shot_ext = updateDmShot; |
| |
| shot_stream = (struct camera2_stream *)buffer->addr[1]; |
| CLOGD("DEBUG(%s[%d]): Selected fcount(hal : %d / driver : %d)", __FUNCTION__, __LINE__, |
| bayerFrame->getFrameCount(), shot_stream->fcount); |
| } else { |
| CLOGE("ERR(%s[%d]): reprocessing is not valid pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId, ret); |
| goto CLEAN; |
| } |
| |
| if (m_exynosCameraParameters->getCaptureExposureTime() != 0 && |
| (shot_ext->shot.dm.sensor.exposureTime / 1000) != m_exynosCameraParameters->getLongExposureTime()) { |
| trycount++; |
| |
| if (((trycount - (int)m_longExposureRemainCount) >= 3) && m_longExposureRemainCount < 3) { |
| m_exynosCameraParameters->setPreviewExposureTime(); |
| } |
| |
| if (buffer->index != -2 && m_bayerBufferMgr != NULL) |
| m_putBuffers(m_bayerBufferMgr, buffer->index); |
| |
| if (bayerFrame != NULL) { |
| bayerFrame->frameUnlock(); |
| ret = m_searchFrameFromList(&m_processList, bayerFrame->getFrameCount(), &inListFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):searchFrameFromList fail", __FUNCTION__, __LINE__); |
| } else { |
| CLOGD("DEBUG(%s[%d]): Selected frame(%d, %d msec) is not same with set from user.", |
| __FUNCTION__, __LINE__, bayerFrame->getFrameCount(), |
| (int) shot_ext->shot.dm.sensor.exposureTime); |
| bayerFrame->decRef(); |
| m_frameMgr->deleteFrame(bayerFrame); |
| bayerFrame = NULL; |
| } |
| } |
| goto BAYER_RETRY; |
| } |
| |
| #ifdef SAMSUNG_DNG |
| if (m_dngFrameNumberForManualExposure == 0) |
| m_dngFrameNumberForManualExposure = shot_ext->shot.dm.request.frameCount; |
| #endif |
| if (m_exynosCameraParameters->getCaptureExposureTime() != 0 && |
| m_longExposureRemainCount > 0) { |
| if (saveBuffer == NULL) { |
| saveBuffer = buffer; |
| buffer = &tempBuffer; |
| tempBuffer.index = -2; |
| |
| if (bayerFrame != NULL) { |
| bayerFrame->frameUnlock(); |
| ret = m_searchFrameFromList(&m_processList, bayerFrame->getFrameCount(), &inListFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):searchFrameFromList fail", __FUNCTION__, __LINE__); |
| } else { |
| bayerFrame->decRef(); |
| m_frameMgr->deleteFrame(bayerFrame); |
| bayerFrame = NULL; |
| } |
| } |
| goto BAYER_RETRY; |
| } |
| |
| #ifdef CAMERA_PACKED_BAYER_ENABLE |
| ret = addBayerBuffer(buffer, saveBuffer, &dstRect, true); |
| #else |
| ret = addBayerBuffer(buffer, saveBuffer, &dstRect); |
| #endif |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):addBayerBufferPacked() fail", __FUNCTION__, __LINE__); |
| } |
| |
| if (buffer->index != -2 && m_bayerBufferMgr != NULL) |
| m_putBuffers(m_bayerBufferMgr, buffer->index); |
| |
| if (bayerFrame != NULL) { |
| bayerFrame->frameUnlock(); |
| |
| ret = m_searchFrameFromList(&m_processList, bayerFrame->getFrameCount(), &inListFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):searchFrameFromList fail", __FUNCTION__, __LINE__); |
| } else { |
| CLOGD("DEBUG(%s[%d]): Selected frame(%d, %d msec) delete.", |
| __FUNCTION__, __LINE__, bayerFrame->getFrameCount(), |
| (int) shot_ext->shot.dm.sensor.exposureTime); |
| bayerFrame->decRef(); |
| m_frameMgr->deleteFrame(bayerFrame); |
| bayerFrame = NULL; |
| } |
| } |
| m_longExposureRemainCount--; |
| if (m_longExposureRemainCount > 0) { |
| if (m_longExposureRemainCount < 3) { |
| m_exynosCameraParameters->setPreviewExposureTime(); |
| } |
| goto BAYER_RETRY; |
| } |
| buffer = saveBuffer; |
| saveBuffer = NULL; |
| |
| #ifdef CAMERA_ADD_BAYER_ENABLE |
| if (mIonClient >= 0) |
| ion_sync_fd(mIonClient, buffer->fd[0]); |
| #endif |
| } |
| |
| if (m_exynosCameraParameters->getCaptureExposureTime() > CAMERA_PREVIEW_EXPOSURE_TIME_LIMIT) { |
| if (m_pictureThread->isRunning() == false) { |
| ret = m_pictureThread->run(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):couldn't run picture thread, ret(%d)", __FUNCTION__, __LINE__, ret); |
| return INVALID_OPERATION; |
| |
| } |
| } |
| |
| if (m_jpegCallbackThread->isRunning() == false) { |
| ret = m_jpegCallbackThread->run(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):couldn't run jpeg callback thread, ret(%d)", __FUNCTION__, __LINE__, ret); |
| return INVALID_OPERATION; |
| } |
| } |
| } |
| |
| m_exynosCameraParameters->setPreviewExposureTime(); |
| |
| #ifdef SAMSUNG_DNG |
| if (m_exynosCameraParameters->getDNGCaptureModeOn() && !m_exynosCameraParameters->getCheckMultiFrame()) { |
| m_exynosCameraParameters->setUseDNGCapture(false); |
| m_captureSelector->resetDNGFrameCount(); |
| CLOGD("DNG(%s[%d]): getUseDNGCapture(%d) flitecount(%d)", __FUNCTION__, __LINE__, |
| m_exynosCameraParameters->getUseDNGCapture(), shot_stream->fcount); |
| } |
| #endif |
| |
| #ifdef LLS_REPROCESSING |
| if(m_captureSelector->getIsLastFrame() == false) { |
| if (m_captureSelector->getIsConvertingMeta() == false) { |
| camera2_shot_ext *shot_ext = NULL; |
| shot_ext = (camera2_shot_ext *)(buffer->addr[1]); |
| if (shot_ext != NULL) |
| fliteFcount = shot_ext->shot.dm.request.frameCount; |
| } else { |
| camera2_stream *shot_stream = NULL; |
| shot_stream = (camera2_stream *)(buffer->addr[1]); |
| if (shot_stream != NULL) |
| fliteFcount = shot_stream->fcount; |
| } |
| |
| CLOGD("DEBUG(%s[%d]): LLS Capture ...ing(hal : %d / driver : %d)", __FUNCTION__, __LINE__, |
| bayerFrame->getFrameCount(), fliteFcount); |
| return ret; |
| } |
| #endif |
| |
| CLEAN: |
| if (saveBuffer != NULL && saveBuffer->index != -2 && m_bayerBufferMgr != NULL) { |
| m_putBuffers(m_bayerBufferMgr, saveBuffer->index); |
| saveBuffer->index = -2; |
| } |
| |
| #ifdef LLS_REPROCESSING |
| if (m_exynosCameraParameters->getSeriesShotMode() == SERIES_SHOT_MODE_LLS && m_captureSelector->getIsLastFrame() == true) { |
| m_captureSelector->resetFrameCount(); |
| m_exynosCameraParameters->setLLSCaptureCount(0); |
| } |
| #endif |
| |
| if (bayerFrame != NULL) { |
| bayerFrame->frameUnlock(); |
| |
| ret = m_searchFrameFromList(&m_processList, bayerFrame->getFrameCount(), &inListFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):searchFrameFromList fail", __FUNCTION__, __LINE__); |
| } else { |
| CLOGD("DEBUG(%s[%d]): Selected frame(%d) complete, Delete", __FUNCTION__, __LINE__, bayerFrame->getFrameCount()); |
| bayerFrame->decRef(); |
| m_frameMgr->deleteFrame(bayerFrame); |
| bayerFrame = NULL; |
| } |
| } |
| |
| return ret; |
| } |
| |
| status_t ExynosCamera::m_checkBufferAvailable(uint32_t pipeId, ExynosCameraBufferManager *bufferMgr) |
| { |
| status_t ret = TIMED_OUT; |
| int retry = 0; |
| |
| do { |
| ret = -1; |
| retry++; |
| if (bufferMgr->getNumOfAvailableBuffer() > 0) { |
| ret = OK; |
| } else { |
| /* wait available ISP buffer */ |
| usleep(WAITING_TIME); |
| } |
| if (retry % 10 == 0) |
| CLOGW("WRAN(%s[%d]):retry(%d) setupEntity for pipeId(%d)", __FUNCTION__, __LINE__, retry, pipeId); |
| } while(ret < 0 && retry < (TOTAL_WAITING_TIME/WAITING_TIME) && m_stopBurstShot == false); |
| |
| return ret; |
| } |
| |
| status_t ExynosCamera::m_boostDynamicCapture(void) |
| { |
| status_t ret = NO_ERROR; |
| #if 0 /* TODO: need to implementation for bayer */ |
| uint32_t pipeId = (isOwnScc(getCameraId()) == true) ? PIPE_SCC : PIPE_ISPC; |
| uint32_t size = m_processList.size(); |
| |
| ExynosCameraFrame *curFrame = NULL; |
| List<ExynosCameraFrame *>::iterator r; |
| camera2_node_group node_group_info_isp; |
| |
| if (m_processList.empty()) { |
| CLOGD("DEBUG(%s[%d]):m_processList is empty", __FUNCTION__, __LINE__); |
| return NO_ERROR; |
| } |
| CLOGD("DEBUG(%s[%d]):m_processList size(%d)", __FUNCTION__, __LINE__, m_processList.size()); |
| r = m_processList.end(); |
| |
| for (unsigned int i = 0; i < 3; i++) { |
| r--; |
| if (r == m_processList.begin()) |
| break; |
| |
| } |
| |
| curFrame = *r; |
| if (curFrame == NULL) { |
| CLOGE("ERR(%s):curFrame is empty", __FUNCTION__); |
| return INVALID_OPERATION; |
| } |
| |
| if (curFrame->getRequest(pipeId) == true) { |
| CLOGD("DEBUG(%s[%d]): Boosting dynamic capture is not need", __FUNCTION__, __LINE__); |
| return NO_ERROR; |
| } |
| |
| CLOGI("INFO(%s[%d]): boosting dynamic capture (frameCount: %d)", __FUNCTION__, __LINE__, curFrame->getFrameCount()); |
| /* For ISP */ |
| curFrame->getNodeGroupInfo(&node_group_info_isp, PERFRAME_INFO_ISP); |
| m_updateBoostDynamicCaptureSize(&node_group_info_isp); |
| curFrame->storeNodeGroupInfo(&node_group_info_isp, PERFRAME_INFO_ISP); |
| |
| curFrame->setRequest(pipeId, true); |
| curFrame->setNumRequestPipe(curFrame->getNumRequestPipe() + 1); |
| |
| ret = curFrame->setEntityState(pipeId, ENTITY_STATE_REWORK); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setEntityState fail, pipeId(%d), state(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId, ENTITY_STATE_REWORK, ret); |
| return ret; |
| } |
| |
| m_previewFrameFactory->pushFrameToPipe(&curFrame, pipeId); |
| m_dynamicSccCount++; |
| CLOGV("DEBUG(%s[%d]): dynamicSccCount inc(%d) frameCount(%d)", __FUNCTION__, __LINE__, m_dynamicSccCount, curFrame->getFrameCount()); |
| #endif |
| |
| return ret; |
| } |
| |
| void ExynosCamera::m_updateBoostDynamicCaptureSize(__unused camera2_node_group *node_group_info) |
| { |
| #if 0 /* TODO: need to implementation for bayer */ |
| ExynosRect sensorSize; |
| ExynosRect bayerCropSize; |
| |
| node_group_info->capture[PERFRAME_BACK_SCC_POS].request = 1; |
| |
| m_exynosCameraParameters->getPreviewBayerCropSize(&sensorSize, &bayerCropSize); |
| |
| node_group_info->leader.input.cropRegion[0] = bayerCropSize.x; |
| node_group_info->leader.input.cropRegion[1] = bayerCropSize.y; |
| node_group_info->leader.input.cropRegion[2] = bayerCropSize.w; |
| node_group_info->leader.input.cropRegion[3] = bayerCropSize.h; |
| node_group_info->leader.output.cropRegion[0] = 0; |
| node_group_info->leader.output.cropRegion[1] = 0; |
| node_group_info->leader.output.cropRegion[2] = node_group_info->leader.input.cropRegion[2]; |
| node_group_info->leader.output.cropRegion[3] = node_group_info->leader.input.cropRegion[3]; |
| |
| /* Capture 0 : SCC - [scaling] */ |
| node_group_info->capture[PERFRAME_BACK_SCC_POS].input.cropRegion[0] = node_group_info->leader.output.cropRegion[0]; |
| node_group_info->capture[PERFRAME_BACK_SCC_POS].input.cropRegion[1] = node_group_info->leader.output.cropRegion[1]; |
| node_group_info->capture[PERFRAME_BACK_SCC_POS].input.cropRegion[2] = node_group_info->leader.output.cropRegion[2]; |
| node_group_info->capture[PERFRAME_BACK_SCC_POS].input.cropRegion[3] = node_group_info->leader.output.cropRegion[3]; |
| |
| node_group_info->capture[PERFRAME_BACK_SCC_POS].output.cropRegion[0] = node_group_info->capture[PERFRAME_BACK_SCC_POS].input.cropRegion[0]; |
| node_group_info->capture[PERFRAME_BACK_SCC_POS].output.cropRegion[1] = node_group_info->capture[PERFRAME_BACK_SCC_POS].input.cropRegion[1]; |
| node_group_info->capture[PERFRAME_BACK_SCC_POS].output.cropRegion[2] = node_group_info->capture[PERFRAME_BACK_SCC_POS].input.cropRegion[2]; |
| node_group_info->capture[PERFRAME_BACK_SCC_POS].output.cropRegion[3] = node_group_info->capture[PERFRAME_BACK_SCC_POS].input.cropRegion[3]; |
| |
| /* Capture 1 : SCP - [scaling] */ |
| node_group_info->capture[PERFRAME_BACK_SCP_POS].input.cropRegion[0] = node_group_info->leader.output.cropRegion[0]; |
| node_group_info->capture[PERFRAME_BACK_SCP_POS].input.cropRegion[1] = node_group_info->leader.output.cropRegion[1]; |
| node_group_info->capture[PERFRAME_BACK_SCP_POS].input.cropRegion[2] = node_group_info->leader.output.cropRegion[2]; |
| node_group_info->capture[PERFRAME_BACK_SCP_POS].input.cropRegion[3] = node_group_info->leader.output.cropRegion[3]; |
| |
| #endif |
| return; |
| } |
| |
| void ExynosCamera::m_checkFpsAndUpdatePipeWaitTime(void) |
| { |
| uint32_t curMinFps = 0; |
| uint32_t curMaxFps = 0; |
| frame_queue_t *inputFrameQ = NULL; |
| |
| m_exynosCameraParameters->getPreviewFpsRange(&curMinFps, &curMaxFps); |
| |
| if (m_curMinFps != curMinFps) { |
| CLOGD("DEBUG(%s[%d]):(%d)(%d)", __FUNCTION__, __LINE__, curMinFps, curMaxFps); |
| |
| enum pipeline pipe = (isOwnScc(getCameraId()) == true) ? PIPE_SCC : PIPE_ISPC; |
| |
| m_previewFrameFactory->getInputFrameQToPipe(&inputFrameQ, pipe); |
| |
| /* 100ms * (30 / 15 fps) = 200ms */ |
| /* 100ms * (30 / 30 fps) = 100ms */ |
| /* 100ms * (30 / 10 fps) = 300ms */ |
| if (inputFrameQ != NULL && curMinFps != 0) |
| inputFrameQ->setWaitTime(((100000000 / curMinFps) * 30)); |
| } |
| |
| m_curMinFps = curMinFps; |
| |
| return; |
| } |
| |
| /* vision */ |
| status_t ExynosCamera::m_startVisionInternal(void) |
| { |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| |
| CLOGI("DEBUG(%s[%d]):IN", __FUNCTION__, __LINE__); |
| |
| uint32_t minFrameNum = FRONT_NUM_BAYER_BUFFERS; |
| int ret = 0; |
| ExynosCameraFrame *newFrame = NULL; |
| ExynosCameraBuffer dstBuf; |
| |
| m_fliteFrameCount = 0; |
| m_3aa_ispFrameCount = 0; |
| m_ispFrameCount = 0; |
| m_sccFrameCount = 0; |
| m_scpFrameCount = 0; |
| m_displayPreviewToggle = 0; |
| |
| ret = m_visionFrameFactory->initPipes(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_visionFrameFactory->initPipes() failed", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| m_visionFps = 10; |
| m_visionAe = 0x2A; |
| |
| ret = m_visionFrameFactory->setControl(V4L2_CID_SENSOR_SET_FRAME_RATE, m_visionFps, PIPE_FLITE); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):FLITE setControl fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| |
| CLOGD("DEBUG(%s[%d]):m_visionFps(%d)", __FUNCTION__, __LINE__, m_visionFps); |
| |
| ret = m_visionFrameFactory->setControl(V4L2_CID_SENSOR_SET_AE_TARGET, m_visionAe, PIPE_FLITE); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):FLITE setControl fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| |
| CLOGD("DEBUG(%s[%d]):m_visionAe(%d)", __FUNCTION__, __LINE__, m_visionAe); |
| |
| for (uint32_t i = 0; i < minFrameNum; i++) { |
| ret = generateFrameVision(i, &newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):generateFrame fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| if (newFrame == NULL) { |
| CLOGE("ERR(%s[%d]):new faame is NULL", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| m_fliteFrameCount++; |
| |
| m_setupEntity(PIPE_FLITE, newFrame); |
| m_visionFrameFactory->setOutputFrameQToPipe(m_pipeFrameVisionDoneQ, PIPE_FLITE); |
| m_visionFrameFactory->pushFrameToPipe(&newFrame, PIPE_FLITE); |
| } |
| |
| /* prepare pipes */ |
| ret = m_visionFrameFactory->preparePipes(); |
| if (ret < 0) { |
| CLOGE("ERR(%s):preparePipe fail", __FUNCTION__); |
| return ret; |
| } |
| |
| /* stream on pipes */ |
| ret = m_visionFrameFactory->startPipes(); |
| if (ret < 0) { |
| CLOGE("ERR(%s):startPipe fail", __FUNCTION__); |
| return ret; |
| } |
| |
| /* start all thread */ |
| ret = m_visionFrameFactory->startInitialThreads(); |
| if (ret < 0) { |
| CLOGE("ERR(%s):startInitialThreads fail", __FUNCTION__); |
| return ret; |
| } |
| |
| m_previewEnabled = true; |
| m_exynosCameraParameters->setPreviewRunning(m_previewEnabled); |
| |
| CLOGI("DEBUG(%s[%d]):OUT", __FUNCTION__, __LINE__); |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_stopVisionInternal(void) |
| { |
| int ret = 0; |
| |
| CLOGI("DEBUG(%s[%d]):IN", __FUNCTION__, __LINE__); |
| |
| ret = m_visionFrameFactory->stopPipes(); |
| if (ret < 0) { |
| CLOGE("ERR(%s):stopPipe fail", __FUNCTION__); |
| return ret; |
| } |
| |
| CLOGD("DEBUG(%s[%d]):clear process Frame list", __FUNCTION__, __LINE__); |
| ret = m_clearList(&m_processList); |
| if (ret < 0) { |
| CLOGE("ERR(%s):m_clearList fail", __FUNCTION__); |
| return ret; |
| } |
| |
| m_clearList(m_pipeFrameVisionDoneQ); |
| |
| m_fliteFrameCount = 0; |
| m_3aa_ispFrameCount = 0; |
| m_ispFrameCount = 0; |
| m_sccFrameCount = 0; |
| m_scpFrameCount = 0; |
| |
| m_previewEnabled = false; |
| m_exynosCameraParameters->setPreviewRunning(m_previewEnabled); |
| |
| CLOGI("DEBUG(%s[%d]):OUT", __FUNCTION__, __LINE__); |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::generateFrameVision(int32_t frameCount, ExynosCameraFrame **newFrame) |
| { |
| Mutex::Autolock lock(m_frameLock); |
| |
| int ret = 0; |
| *newFrame = NULL; |
| |
| if (frameCount >= 0) { |
| ret = m_searchFrameFromList(&m_processList, frameCount, newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):searchFrameFromList fail", __FUNCTION__, __LINE__); |
| return INVALID_OPERATION; |
| } |
| } |
| |
| if (*newFrame == NULL) { |
| *newFrame = m_visionFrameFactory->createNewFrame(); |
| |
| if (*newFrame == NULL) { |
| CLOGE("ERR(%s):newFrame is NULL", __FUNCTION__); |
| return UNKNOWN_ERROR; |
| } |
| |
| m_processList.push_back(*newFrame); |
| } |
| |
| return ret; |
| } |
| |
| status_t ExynosCamera::m_setVisionBuffers(void) |
| { |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| |
| CLOGI("INFO(%s[%d]):alloc buffer - camera ID: %d", |
| __FUNCTION__, __LINE__, m_cameraId); |
| int ret = 0; |
| unsigned int bytesPerLine[EXYNOS_CAMERA_BUFFER_MAX_PLANES] = {0}; |
| unsigned int planeSize[EXYNOS_CAMERA_BUFFER_MAX_PLANES] = {0}; |
| int hwPreviewW, hwPreviewH; |
| int hwSensorW, hwSensorH; |
| int hwPictureW, hwPictureH; |
| |
| int previewMaxW, previewMaxH; |
| int sensorMaxW, sensorMaxH; |
| |
| int planeCount = 1; |
| int minBufferCount = 1; |
| int maxBufferCount = 1; |
| |
| maxBufferCount = FRONT_NUM_BAYER_BUFFERS; |
| planeSize[0] = VISION_WIDTH * VISION_HEIGHT; |
| planeCount = 2; |
| exynos_camera_buffer_type_t type = EXYNOS_CAMERA_BUFFER_ION_NONCACHED_TYPE; |
| |
| /* ret = m_allocBuffers(m_bayerBufferMgr, planeCount, planeSize, bytesPerLine, maxBufferCount, maxBufferCount, type, true, false); */ |
| ret = m_allocBuffers(m_bayerBufferMgr, planeCount, planeSize, bytesPerLine, maxBufferCount, maxBufferCount, type, true, true); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):bayerBuffer m_allocBuffers(bufferCount=%d) fail", |
| __FUNCTION__, __LINE__, maxBufferCount); |
| return ret; |
| } |
| |
| CLOGI("INFO(%s[%d]):alloc buffer done - camera ID: %d", |
| __FUNCTION__, __LINE__, m_cameraId); |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_setVisionCallbackBuffer(void) |
| { |
| int ret = 0; |
| int previewW = 0, previewH = 0; |
| int previewFormat = 0; |
| m_exynosCameraParameters->getPreviewSize(&previewW, &previewH); |
| previewFormat = m_exynosCameraParameters->getPreviewFormat(); |
| |
| unsigned int planeSize[EXYNOS_CAMERA_BUFFER_MAX_PLANES] = {0}; |
| unsigned int bytesPerLine[EXYNOS_CAMERA_BUFFER_MAX_PLANES] = {0}; |
| |
| int planeCount = getYuvPlaneCount(previewFormat); |
| int bufferCount = FRONT_NUM_BAYER_BUFFERS; |
| exynos_camera_buffer_type_t type = EXYNOS_CAMERA_BUFFER_ION_CACHED_TYPE; |
| |
| planeSize[0] = VISION_WIDTH * VISION_HEIGHT; |
| planeCount = 1; |
| ret = m_allocBuffers(m_previewCallbackBufferMgr, planeCount, planeSize, bytesPerLine, bufferCount, bufferCount, type, false, true); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_previewCallbackBufferMgr m_allocBuffers(bufferCount=%d) fail", |
| __FUNCTION__, __LINE__, bufferCount); |
| return ret; |
| } |
| |
| return NO_ERROR; |
| } |
| |
| |
| bool ExynosCamera::m_visionThreadFunc(void) |
| { |
| int ret = 0; |
| int index = 0; |
| |
| int frameSkipCount = 0; |
| ExynosCameraFrameEntity *entity = NULL; |
| ExynosCameraFrame *handleFrame = NULL; |
| ExynosCameraFrame *newFrame = NULL; |
| ExynosCameraBuffer bayerBuffer; |
| int pipeID = 0; |
| /* to handle the high speed frame rate */ |
| bool skipPreview = false; |
| int ratio = 1; |
| uint32_t minFps = 0, maxFps = 0; |
| uint32_t dispFps = EXYNOS_CAMERA_PREVIEW_FPS_REFERENCE; |
| uint32_t fvalid = 0; |
| uint32_t fcount = 0; |
| struct camera2_stream *shot_stream = NULL; |
| size_t callbackBufSize; |
| status_t statusRet = NO_ERROR; |
| int fps = 0; |
| int ae = 0; |
| int internalValue = 0; |
| |
| if (m_previewEnabled == false) { |
| CLOGD("DEBUG(%s):preview is stopped, thread stop", __FUNCTION__); |
| return false; |
| } |
| |
| ret = m_pipeFrameVisionDoneQ->waitAndPopProcessQ(&handleFrame); |
| if (ret < 0) { |
| /* TODO: We need to make timeout duration depends on FPS */ |
| if (ret == TIMED_OUT) { |
| CLOGW("WARN(%s):wait timeout", __FUNCTION__); |
| } else { |
| CLOGE("ERR(%s):wait and pop fail, ret(%d)", __FUNCTION__, ret); |
| /* TODO: doing exception handling */ |
| } |
| return true; |
| } |
| |
| if (handleFrame == NULL) { |
| CLOGE("ERR(%s[%d]):handleFrame is NULL", __FUNCTION__, __LINE__); |
| return true; |
| } |
| |
| /* handle vision frame */ |
| entity = handleFrame->getFrameDoneEntity(); |
| if (entity == NULL) { |
| CLOGE("ERR(%s[%d]):current entity is NULL", __FUNCTION__, __LINE__); |
| /* TODO: doing exception handling */ |
| return true; |
| } |
| |
| pipeID = entity->getPipeId(); |
| |
| switch(entity->getPipeId()) { |
| case PIPE_FLITE: |
| ret = handleFrame->getDstBuffer(entity->getPipeId(), &bayerBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ret); |
| return ret; |
| } |
| |
| #ifdef VISION_DUMP |
| char filePath[50]; |
| snprintf(filePath, sizeof(filePath), "/data/media/0/DCIM/Camera/vision%02d.raw", dumpIndex); |
| CLOGD("vision dump %s", filePath); |
| dumpToFile(filePath, (char *)bayerBuffer.addr[0], VISION_WIDTH * VISION_HEIGHT); |
| |
| dumpIndex ++; |
| if (dumpIndex > 4) |
| dumpIndex = 0; |
| #endif |
| |
| m_exynosCameraParameters->getFrameSkipCount(&frameSkipCount); |
| |
| if (frameSkipCount > 0) { |
| CLOGD("INFO(%s[%d]):frameSkipCount(%d)", __FUNCTION__, __LINE__, frameSkipCount); |
| } else { |
| /* callback */ |
| if (m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) { |
| ExynosCameraBuffer previewCbBuffer; |
| camera_memory_t *previewCallbackHeap = NULL; |
| char *srcAddr = NULL; |
| char *dstAddr = NULL; |
| int bufIndex = -2; |
| |
| m_previewCallbackBufferMgr->getBuffer(&bufIndex, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL, &previewCbBuffer); |
| previewCallbackHeap = m_getMemoryCb(previewCbBuffer.fd[0], previewCbBuffer.size[0], 1, m_callbackCookie); |
| if (!previewCallbackHeap || previewCallbackHeap->data == MAP_FAILED) { |
| CLOGE("ERR(%s[%d]):m_getMemoryCb(fd:%d, size:%d) fail", __FUNCTION__, __LINE__, previewCbBuffer.fd[0], previewCbBuffer.size[0]); |
| |
| return INVALID_OPERATION; |
| } |
| |
| for (int plane = 0; plane < 1; plane++) { |
| srcAddr = bayerBuffer.addr[plane]; |
| dstAddr = (char *)previewCallbackHeap->data; |
| memcpy(dstAddr, srcAddr, previewCbBuffer.size[plane]); |
| } |
| #if 0 |
| // Getting the buffer size for current preview size. |
| callbackBufSize = m_getCurrentPreviewSizeBytes(); |
| if (callbackBufSize <= 0) { |
| CLOGE("ERR(%s[%d]): m_getCurrentPreviewSizeBytes fail, ret(%d)", __FUNCTION__, __LINE__, callbackBufSize); |
| statusRet = INVALID_OPERATION; |
| // goto done; |
| } |
| |
| // Comparing newely updated preview buffer size against previewCallbackHeap. |
| // If size is different, it means that the preview size has changed |
| // during the memory transfer or GSC operations. So we have to drop this |
| // preview callback buffer to prevent malfunctioning of user application |
| if (previewCallbackHeap->size != callbackBufSize) { |
| CLOGW("WARN(%s[%d]): Preview size changed during operation. " \ |
| "Initial=[%d], Current=[%d]. Current preview frame[%d] will be dropped." |
| , __FUNCTION__, __LINE__, previewCallbackHeap->size, callbackBufSize, handleFrame->getFrameCount()); |
| // goto done; |
| } |
| #endif |
| setBit(&m_callbackState, CALLBACK_STATE_PREVIEW_FRAME, true); |
| m_dataCb(CAMERA_MSG_PREVIEW_FRAME, previewCallbackHeap, 0, NULL, m_callbackCookie); |
| clearBit(&m_callbackState, CALLBACK_STATE_PREVIEW_FRAME, true); |
| |
| previewCallbackHeap->release(previewCallbackHeap); |
| |
| m_previewCallbackBufferMgr->putBuffer(bufIndex, EXYNOS_CAMERA_BUFFER_POSITION_NONE); |
| } |
| } |
| |
| ret = m_putBuffers(m_bayerBufferMgr, bayerBuffer.index); |
| |
| ret = generateFrameVision(m_fliteFrameCount, &newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):generateFrame fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| ret = m_setupEntity(PIPE_FLITE, newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail", __FUNCTION__, __LINE__); |
| break; |
| } |
| |
| m_visionFrameFactory->setOutputFrameQToPipe(m_pipeFrameVisionDoneQ, PIPE_FLITE); |
| m_visionFrameFactory->pushFrameToPipe(&newFrame, PIPE_FLITE); |
| m_fliteFrameCount++; |
| |
| break; |
| default: |
| break; |
| } |
| |
| ret = handleFrame->setEntityState(entity->getPipeId(), ENTITY_STATE_COMPLETE); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setEntityState fail, pipeId(%d), state(%d), ret(%d)", |
| __FUNCTION__, __LINE__, entity->getPipeId(), ENTITY_STATE_COMPLETE, ret); |
| return ret; |
| } |
| |
| CLOGV("DEBUG(%s[%d]):frame complete, count(%d)", __FUNCTION__, __LINE__, handleFrame->getFrameCount()); |
| ret = m_removeFrameFromList(&m_processList, handleFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):remove frame from processList fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| |
| handleFrame->decRef(); |
| m_frameMgr->deleteFrame(handleFrame); |
| handleFrame = NULL; |
| |
| #if 1 |
| fps = m_exynosCameraParameters->getVisionModeFps(); |
| if (m_visionFps != fps) { |
| ret = m_visionFrameFactory->setControl(V4L2_CID_SENSOR_SET_FRAME_RATE, fps, PIPE_FLITE); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):FLITE setControl fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| |
| m_visionFps = fps; |
| CLOGD("DEBUG(%s[%d]):(%d)(%d)", __FUNCTION__, __LINE__, m_visionFps, fps); |
| } |
| #if 0 |
| if (0 < m_visionAeTarget) { |
| if (m_visionAeTarget != m_exynosVision->getAeTarget()) { |
| if (m_exynosVision->setAeTarget(m_visionAeTarget) == false) { |
| CLOGE("ERR(%s): Fail to setAeTarget(%d)", __func__, m_visionAeTarget); |
| |
| goto err; |
| } |
| } |
| } |
| #endif |
| |
| ae = m_exynosCameraParameters->getVisionModeAeTarget(); |
| if (ae != m_visionAe) { |
| switch(ae) { |
| case 1: |
| internalValue = 0x2A; |
| break; |
| case 2: |
| internalValue = 0x8A; |
| break; |
| default: |
| internalValue = 0x2A; |
| break; |
| } |
| |
| ret = m_visionFrameFactory->setControl(V4L2_CID_SENSOR_SET_AE_TARGET, internalValue, PIPE_FLITE); |
| if (ret < 0) |
| CLOGE("ERR(%s[%d]):FLITE setControl fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| |
| m_visionAe = ae; |
| CLOGD("DEBUG(%s[%d]):(%d)(%d)", __FUNCTION__, __LINE__, m_visionAe, internalValue); |
| } |
| #endif |
| |
| |
| |
| return true; |
| } |
| |
| void ExynosCamera::m_printExynosCameraInfo(const char *funcName) |
| { |
| int w = 0; |
| int h = 0; |
| ExynosRect srcRect, dstRect; |
| |
| CLOGD("DEBUG(%s[%d]):===================================================", __FUNCTION__, __LINE__); |
| CLOGD("DEBUG(%s[%d]):============= ExynosCameraInfo call by %s", __FUNCTION__, __LINE__, funcName); |
| CLOGD("DEBUG(%s[%d]):===================================================", __FUNCTION__, __LINE__); |
| |
| CLOGD("DEBUG(%s[%d]):============= Scenario ============================", __FUNCTION__, __LINE__); |
| CLOGD("DEBUG(%s[%d]):= getCameraId : %d", __FUNCTION__, __LINE__, m_exynosCameraParameters->getCameraId()); |
| CLOGD("DEBUG(%s[%d]):= getDualMode : %d", __FUNCTION__, __LINE__, m_exynosCameraParameters->getDualMode()); |
| CLOGD("DEBUG(%s[%d]):= getScalableSensorMode : %d", __FUNCTION__, __LINE__, m_exynosCameraParameters->getScalableSensorMode()); |
| CLOGD("DEBUG(%s[%d]):= getRecordingHint : %d", __FUNCTION__, __LINE__, m_exynosCameraParameters->getRecordingHint()); |
| CLOGD("DEBUG(%s[%d]):= getEffectRecordingHint : %d", __FUNCTION__, __LINE__, m_exynosCameraParameters->getEffectRecordingHint()); |
| CLOGD("DEBUG(%s[%d]):= getDualRecordingHint : %d", __FUNCTION__, __LINE__, m_exynosCameraParameters->getDualRecordingHint()); |
| CLOGD("DEBUG(%s[%d]):= getAdaptiveCSCRecording : %d", __FUNCTION__, __LINE__, m_exynosCameraParameters->getAdaptiveCSCRecording()); |
| CLOGD("DEBUG(%s[%d]):= doCscRecording : %d", __FUNCTION__, __LINE__, m_exynosCameraParameters->doCscRecording()); |
| CLOGD("DEBUG(%s[%d]):= needGSCForCapture : %d", __FUNCTION__, __LINE__, needGSCForCapture(getCameraId())); |
| CLOGD("DEBUG(%s[%d]):= getShotMode : %d", __FUNCTION__, __LINE__, m_exynosCameraParameters->getShotMode()); |
| CLOGD("DEBUG(%s[%d]):= getTpuEnabledMode : %d", __FUNCTION__, __LINE__, m_exynosCameraParameters->getTpuEnabledMode()); |
| CLOGD("DEBUG(%s[%d]):= getHWVdisMode : %d", __FUNCTION__, __LINE__, m_exynosCameraParameters->getHWVdisMode()); |
| CLOGD("DEBUG(%s[%d]):= get3dnrMode : %d", __FUNCTION__, __LINE__, m_exynosCameraParameters->get3dnrMode()); |
| |
| CLOGD("DEBUG(%s[%d]):============= Internal setting ====================", __FUNCTION__, __LINE__); |
| CLOGD("DEBUG(%s[%d]):= isFlite3aaOtf : %d", __FUNCTION__, __LINE__, m_exynosCameraParameters->isFlite3aaOtf()); |
| CLOGD("DEBUG(%s[%d]):= is3aaIspOtf : %d", __FUNCTION__, __LINE__, m_exynosCameraParameters->is3aaIspOtf()); |
| CLOGD("DEBUG(%s[%d]):= isIspTpuOtf : %d", __FUNCTION__, __LINE__, m_exynosCameraParameters->isIspTpuOtf()); |
| CLOGD("DEBUG(%s[%d]):= isReprocessing : %d", __FUNCTION__, __LINE__, m_exynosCameraParameters->isReprocessing()); |
| CLOGD("DEBUG(%s[%d]):= isReprocessing3aaIspOTF : %d", __FUNCTION__, __LINE__, m_exynosCameraParameters->isReprocessing3aaIspOTF()); |
| CLOGD("DEBUG(%s[%d]):= getUsePureBayerReprocessing : %d", __FUNCTION__, __LINE__, m_exynosCameraParameters->getUsePureBayerReprocessing()); |
| |
| int reprocessingBayerMode = m_exynosCameraParameters->getReprocessingBayerMode(); |
| switch(reprocessingBayerMode) { |
| case REPROCESSING_BAYER_MODE_NONE: |
| CLOGD("DEBUG(%s[%d]):= getReprocessingBayerMode : REPROCESSING_BAYER_MODE_NONE", __FUNCTION__, __LINE__); |
| break; |
| case REPROCESSING_BAYER_MODE_PURE_ALWAYS_ON: |
| CLOGD("DEBUG(%s[%d]):= getReprocessingBayerMode : REPROCESSING_BAYER_MODE_PURE_ALWAYS_ON", __FUNCTION__, __LINE__); |
| break; |
| case REPROCESSING_BAYER_MODE_DIRTY_ALWAYS_ON: |
| CLOGD("DEBUG(%s[%d]):= getReprocessingBayerMode : REPROCESSING_BAYER_MODE_DIRTY_ALWAYS_ON", __FUNCTION__, __LINE__); |
| break; |
| case REPROCESSING_BAYER_MODE_PURE_DYNAMIC: |
| CLOGD("DEBUG(%s[%d]):= getReprocessingBayerMode : REPROCESSING_BAYER_MODE_PURE_DYNAMIC", __FUNCTION__, __LINE__); |
| break; |
| case REPROCESSING_BAYER_MODE_DIRTY_DYNAMIC: |
| CLOGD("DEBUG(%s[%d]):= getReprocessingBayerMode : REPROCESSING_BAYER_MODE_DIRTY_DYNAMIC", __FUNCTION__, __LINE__); |
| break; |
| default: |
| CLOGD("DEBUG(%s[%d]):= getReprocessingBayerMode : unexpected mode %d", __FUNCTION__, __LINE__, reprocessingBayerMode); |
| break; |
| } |
| |
| CLOGD("DEBUG(%s[%d]):= isSccCapture : %d", __FUNCTION__, __LINE__, m_exynosCameraParameters->isSccCapture()); |
| |
| CLOGD("DEBUG(%s[%d]):============= size setting =======================", __FUNCTION__, __LINE__); |
| m_exynosCameraParameters->getMaxSensorSize(&w, &h); |
| CLOGD("DEBUG(%s[%d]):= getMaxSensorSize : %d x %d", __FUNCTION__, __LINE__, w, h); |
| |
| m_exynosCameraParameters->getHwSensorSize(&w, &h); |
| CLOGD("DEBUG(%s[%d]):= getHwSensorSize : %d x %d", __FUNCTION__, __LINE__, w, h); |
| |
| m_exynosCameraParameters->getBnsSize(&w, &h); |
| CLOGD("DEBUG(%s[%d]):= getBnsSize : %d x %d", __FUNCTION__, __LINE__, w, h); |
| |
| m_exynosCameraParameters->getPreviewBayerCropSize(&srcRect, &dstRect); |
| CLOGD("DEBUG(%s[%d]):= getPreviewBayerCropSize : (%d, %d, %d, %d) -> (%d, %d, %d, %d)", __FUNCTION__, __LINE__, |
| srcRect.x, srcRect.y, srcRect.w, srcRect.h, |
| dstRect.x, dstRect.y, dstRect.w, dstRect.h); |
| |
| m_exynosCameraParameters->getPreviewBdsSize(&dstRect); |
| CLOGD("DEBUG(%s[%d]):= getPreviewBdsSize : (%d, %d, %d, %d)", __FUNCTION__, __LINE__, |
| dstRect.x, dstRect.y, dstRect.w, dstRect.h); |
| |
| m_exynosCameraParameters->getHwPreviewSize(&w, &h); |
| CLOGD("DEBUG(%s[%d]):= getHwPreviewSize : %d x %d", __FUNCTION__, __LINE__, w, h); |
| |
| m_exynosCameraParameters->getPreviewSize(&w, &h); |
| CLOGD("DEBUG(%s[%d]):= getPreviewSize : %d x %d", __FUNCTION__, __LINE__, w, h); |
| |
| m_exynosCameraParameters->getPictureBayerCropSize(&srcRect, &dstRect); |
| CLOGD("DEBUG(%s[%d]):= getPictureBayerCropSize : (%d, %d, %d, %d) -> (%d, %d, %d, %d)", __FUNCTION__, __LINE__, |
| srcRect.x, srcRect.y, srcRect.w, srcRect.h, |
| dstRect.x, dstRect.y, dstRect.w, dstRect.h); |
| |
| m_exynosCameraParameters->getPictureBdsSize(&dstRect); |
| CLOGD("DEBUG(%s[%d]):= getPictureBdsSize : (%d, %d, %d, %d)", __FUNCTION__, __LINE__, |
| dstRect.x, dstRect.y, dstRect.w, dstRect.h); |
| |
| m_exynosCameraParameters->getHwPictureSize(&w, &h); |
| CLOGD("DEBUG(%s[%d]):= getHwPictureSize : %d x %d", __FUNCTION__, __LINE__, w, h); |
| |
| m_exynosCameraParameters->getPictureSize(&w, &h); |
| CLOGD("DEBUG(%s[%d]):= getPictureSize : %d x %d", __FUNCTION__, __LINE__, w, h); |
| |
| CLOGD("DEBUG(%s[%d]):===================================================", __FUNCTION__, __LINE__); |
| } |
| |
| status_t ExynosCamera::m_startCompanion(void) |
| { |
| #if defined(SAMSUNG_COMPANION) |
| if(m_use_companion == true) { |
| if (m_companionNode == NULL) { |
| m_companionThread = new mainCameraThread(this, &ExynosCamera::m_companionThreadFunc, |
| "companionshotThread", PRIORITY_URGENT_DISPLAY); |
| if (m_companionThread != NULL) { |
| m_companionThread->run(); |
| CLOGD("DEBUG(%s): companionThread starts", __FUNCTION__); |
| } else { |
| CLOGE("(%s):failed the m_companionThread.", __FUNCTION__); |
| } |
| } else { |
| CLOGW("WRN(%s[%d]):m_companionNode != NULL. so, it already running", __FUNCTION__, __LINE__); |
| } |
| } |
| #endif |
| |
| #if defined(SAMSUNG_EEPROM) |
| if ((m_use_companion == false) && (isEEprom(getCameraId()) == true)) { |
| m_eepromThread = new mainCameraThread(this, &ExynosCamera::m_eepromThreadFunc, |
| "cameraeepromThread", PRIORITY_URGENT_DISPLAY); |
| if (m_eepromThread != NULL) { |
| m_eepromThread->run(); |
| CLOGD("DEBUG(%s): eepromThread starts", __FUNCTION__); |
| } else { |
| CLOGE("(%s): failed the m_eepromThread", __FUNCTION__); |
| } |
| } |
| #endif |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_stopCompanion(void) |
| { |
| #if defined(SAMSUNG_COMPANION) |
| if(m_use_companion == true) { |
| if (m_companionThread != NULL) { |
| CLOGI("INFO(%s[%d]): wait m_companionThread", __FUNCTION__, __LINE__); |
| m_companionThread->requestExitAndWait(); |
| CLOGI("INFO(%s[%d]): wait m_companionThread end", __FUNCTION__, __LINE__); |
| } else { |
| CLOGI("INFO(%s[%d]): m_companionThread is NULL", __FUNCTION__, __LINE__); |
| } |
| |
| if (m_companionNode != NULL) { |
| ExynosCameraDurationTimer timer; |
| |
| timer.start(); |
| |
| if (m_companionNode->close() != NO_ERROR) { |
| CLOGE("ERR(%s):close fail", __FUNCTION__); |
| } |
| delete m_companionNode; |
| m_companionNode = NULL; |
| |
| CLOGD("DEBUG(%s):Companion Node(%d) closed", __FUNCTION__, MAIN_CAMERA_COMPANION_NUM); |
| |
| timer.stop(); |
| CLOGD("DEBUG(%s[%d]):duration time(%5d msec)", __FUNCTION__, __LINE__, (int)timer.durationMsecs()); |
| |
| } |
| } |
| #endif |
| |
| #if defined(SAMSUNG_EEPROM) |
| if ((m_use_companion == false) && (isEEprom(getCameraId()) == true)) { |
| if (m_eepromThread != NULL) { |
| CLOGI("INFO(%s[%d]): wait m_eepromThread", __FUNCTION__, __LINE__); |
| m_eepromThread->requestExitAndWait(); |
| } else { |
| CLOGI("INFO(%s[%d]): m_eepromThread is NULL", __FUNCTION__, __LINE__); |
| } |
| } |
| #endif |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::m_waitCompanionThreadEnd(void) |
| { |
| ExynosCameraDurationTimer timer; |
| |
| timer.start(); |
| |
| #ifdef SAMSUNG_COMPANION |
| if(m_use_companion == true) { |
| if (m_companionThread != NULL) { |
| m_companionThread->join(); |
| } else { |
| CLOGI("INFO(%s[%d]):m_companionThread is NULL", __FUNCTION__, __LINE__); |
| } |
| } |
| #endif |
| |
| timer.stop(); |
| CLOGD("DEBUG(%s[%d]):companion waiting time : duration time(%5d msec)", __FUNCTION__, __LINE__, (int)timer.durationMsecs()); |
| |
| CLOGD("DEBUG(%s[%d]):companionThread join", __FUNCTION__, __LINE__); |
| |
| return NO_ERROR; |
| } |
| |
| #ifdef SAMSUNG_SENSOR_LISTENER |
| bool ExynosCamera::m_sensorListenerThreadFunc(void) |
| { |
| CLOGI("INFO(%s[%d]):", __FUNCTION__, __LINE__); |
| ExynosCameraDurationTimer m_timer; |
| long long durationTime = 0; |
| |
| m_timer.start(); |
| |
| uint32_t curMinFps = 0; |
| uint32_t curMaxFps = 0; |
| |
| m_exynosCameraParameters->getPreviewFpsRange(&curMinFps, &curMaxFps); |
| if(curMinFps > 60 && curMaxFps > 60) |
| goto skip_sensor_listener; |
| |
| #ifdef SAMSUNG_HRM |
| if(getCameraId() == CAMERA_ID_BACK && m_exynosCameraParameters->getSamsungCamera() == true && |
| m_exynosCameraParameters->getVtMode() == 0) { |
| if(m_uv_rayHandle == NULL) { |
| m_uv_rayHandle = sensor_listener_load(); |
| if(m_uv_rayHandle != NULL) { |
| if(sensor_listener_enable_sensor(m_uv_rayHandle, ST_UV_RAY, 10*1000) < 0) { |
| sensor_listener_unload(&m_uv_rayHandle); |
| } else { |
| m_exynosCameraParameters->m_setHRM_Hint(true); |
| } |
| } |
| } else { |
| m_exynosCameraParameters->m_setHRM_Hint(true); |
| } |
| } |
| #endif |
| |
| #ifdef SAMSUNG_LIGHT_IR |
| if(getCameraId() == CAMERA_ID_FRONT && m_exynosCameraParameters->getSamsungCamera() == true && |
| m_exynosCameraParameters->getVtMode() == 0) { |
| if(m_light_irHandle == NULL) { |
| m_light_irHandle = sensor_listener_load(); |
| if(m_light_irHandle != NULL) { |
| if(sensor_listener_enable_sensor(m_light_irHandle, ST_LIGHT_IR, 120*1000) < 0) { |
| sensor_listener_unload(&m_light_irHandle); |
| } else { |
| m_exynosCameraParameters->m_setLight_IR_Hint(true); |
| } |
| } |
| } else { |
| m_exynosCameraParameters->m_setLight_IR_Hint(true); |
| } |
| } |
| #endif |
| |
| #ifdef SAMSUNG_GYRO |
| if(getCameraId() == CAMERA_ID_BACK && m_exynosCameraParameters->getSamsungCamera() == true && |
| m_exynosCameraParameters->getVtMode() == 0) { |
| if(m_gyroHandle == NULL) { |
| m_gyroHandle = sensor_listener_load(); |
| if(m_gyroHandle != NULL) { |
| /* HACK |
| * Below event rate(7700) is set to let gyro timestamp operate |
| * for VDIS performance. Real event rate is 10ms not 7.7ms |
| */ |
| if(sensor_listener_enable_sensor(m_gyroHandle,ST_GYROSCOPE, 7700) < 0) { |
| sensor_listener_unload(&m_gyroHandle); |
| } else { |
| m_exynosCameraParameters->m_setGyroHint(true); |
| } |
| } |
| } else { |
| m_exynosCameraParameters->m_setGyroHint(true); |
| } |
| } |
| #endif |
| |
| skip_sensor_listener: |
| m_timer.stop(); |
| durationTime = m_timer.durationMsecs(); |
| CLOGD("DEBUG(%s):duration time(%5d msec)", __FUNCTION__, (int)durationTime); |
| |
| return false; |
| } |
| #endif /* SAMSUNG_SENSOR_LISTENER */ |
| |
| #ifdef SAMSUNG_LLV_TUNING |
| status_t ExynosCamera::m_checkLLVtuning(void) |
| { |
| FILE *fp = NULL; |
| int i; |
| char filePath[30]; |
| status_t ret = NO_ERROR; |
| |
| for(i = UNI_PLUGIN_POWER_CONTROL_OFF; i <= UNI_PLUGIN_POWER_CONTROL_4; i++) { |
| memset(filePath, 0, sizeof(filePath)); |
| sprintf(filePath, "%s_%d.txt", "/mnt/sdcard/LLVKEY", i); |
| fp = fopen(filePath, "r"); |
| if (fp == NULL) { |
| CLOGE("(%s[%d]):failed to open LLVKEY_%d", __FUNCTION__, __LINE__, i); |
| } |
| else { |
| CLOGD("(%s[%d]):succeeded to open LLVKEY_%d", __FUNCTION__, __LINE__, i); |
| m_LLVpowerLevel = i; |
| fclose(fp); |
| break; |
| } |
| } |
| |
| return NO_ERROR; |
| } |
| #endif |
| |
| #ifdef SAMSUNG_HLV |
| status_t ExynosCamera::m_ProgramAndProcessHLV(ExynosCameraBuffer *FrameBuffer) |
| { |
| UniPluginBufferData_t BufferInfo; |
| int curVideoW = 0, curVideoH = 0; |
| int numValid = 0; |
| int ret = 0; |
| UniPluginFocusData_t *focusData = NULL; |
| |
| m_HLVprocessStep = HLV_PROCESS_PRE; |
| if (FrameBuffer == NULL) { |
| ALOGE("HLV: [%s-%d]: FrameBuffer is NULL - Exit", __FUNCTION__, __LINE__); |
| return -1; |
| } |
| |
| int maxNumFocusAreas = m_exynosCameraParameters->getMaxNumFocusAreas(); |
| if (maxNumFocusAreas <= 0) { |
| ALOGE("HLV: [%s-%d]: maxNumFocusAreas is <= 0 - Exit", __FUNCTION__, __LINE__); |
| return -1; |
| } |
| |
| focusData = new UniPluginFocusData_t[maxNumFocusAreas]; |
| |
| memset(&BufferInfo, 0, sizeof(UniPluginBufferData_t)); |
| memset(focusData, 0, sizeof(UniPluginFocusData_t) * maxNumFocusAreas); |
| |
| m_exynosCameraParameters->getVideoSize(&curVideoW, &curVideoH); |
| |
| BufferInfo.InWidth = curVideoW; |
| BufferInfo.InHeight = curVideoH; |
| BufferInfo.InBuffY = FrameBuffer->addr[0]; |
| BufferInfo.InBuffU = FrameBuffer->addr[1]; |
| BufferInfo.ZoomLevel = m_exynosCameraParameters->getZoomLevel(); |
| BufferInfo.Timestamp = m_lastRecordingTimeStamp / 1000000; /* in MilliSec */ |
| |
| ALOGV("HLV: [%s-%d]: uni_plugin_set BUFFER_INFO", __FUNCTION__, __LINE__); |
| m_HLVprocessStep = HLV_PROCESS_SET; |
| ret = uni_plugin_set(m_HLV, |
| HIGHLIGHT_VIDEO_PLUGIN_NAME, |
| UNI_PLUGIN_INDEX_BUFFER_INFO, |
| &BufferInfo); |
| if (ret < 0) |
| ALOGE("HLV: uni_plugin_set fail!"); |
| |
| |
| ALOGV("HLV: uni_plugin_set FOCUS_INFO"); |
| |
| if (m_exynosCameraParameters->getObjectTrackingEnable()) |
| { |
| ExynosRect2 *objectTrackingArea = new ExynosRect2[maxNumFocusAreas]; |
| int* objectTrackingWeight = new int[maxNumFocusAreas]; |
| int validNumber; |
| |
| m_exynosCameraParameters->getObjectTrackingAreas(&validNumber, |
| objectTrackingArea, objectTrackingWeight); |
| |
| for (int i = 0; i < validNumber; i++) { |
| focusData[i].FocusROILeft = objectTrackingArea[i].x1; |
| focusData[i].FocusROIRight = objectTrackingArea[i].x2; |
| focusData[i].FocusROITop = objectTrackingArea[i].y1; |
| focusData[i].FocusROIBottom = objectTrackingArea[i].y2; |
| focusData[i].FocusWeight = objectTrackingWeight[i]; |
| } |
| |
| if (validNumber > 1) |
| ALOGW("HLV: Valid Focus Area > 1"); |
| |
| delete[] objectTrackingArea; |
| delete[] objectTrackingWeight; |
| } |
| else |
| { |
| int FocusAreaWeight = 0; |
| ExynosRect2 CurrentFocusArea; |
| ExynosCameraActivityAutofocus *autoFocusMgr = m_exynosCameraActivityControl->getAutoFocusMgr(); |
| |
| memset(&CurrentFocusArea, 0, sizeof(ExynosRect2)); |
| autoFocusMgr->getFocusAreas(&CurrentFocusArea, &FocusAreaWeight); |
| |
| focusData[0].FocusROILeft = CurrentFocusArea.x1; |
| focusData[0].FocusROIRight = CurrentFocusArea.x2; |
| focusData[0].FocusROITop = CurrentFocusArea.y1; |
| focusData[0].FocusROIBottom = CurrentFocusArea.y2; |
| focusData[0].FocusWeight = FocusAreaWeight; |
| |
| ALOGV("HLV: CurrentFocusArea : %d, %d, %d, %d", |
| CurrentFocusArea.x1, CurrentFocusArea.x2, |
| CurrentFocusArea.y1, CurrentFocusArea.y2); |
| } |
| |
| ret = uni_plugin_set(m_HLV, |
| HIGHLIGHT_VIDEO_PLUGIN_NAME, |
| UNI_PLUGIN_INDEX_FOCUS_INFO, |
| focusData); |
| if (ret < 0) |
| ALOGE("HLV: uni_plugin_set fail!"); |
| |
| m_HLVprocessStep = HLV_PROCESS_START; |
| ret = uni_plugin_process(m_HLV); |
| if (ret < 0) |
| ALOGE("HLV: uni_plugin_process FAIL"); |
| |
| delete[] focusData; |
| |
| m_HLVprocessStep = HLV_PROCESS_DONE; |
| return ret; |
| } |
| #endif |
| |
| void ExynosCamera::m_checkEntranceLux(struct camera2_shot_ext *meta_shot_ext) { |
| uint32_t data = 0; |
| |
| if (m_checkFirstFrameLux == false || m_exynosCameraParameters->getDualMode() == true || |
| m_exynosCameraParameters->getRecordingHint() == true) { |
| m_checkFirstFrameLux = false; |
| return; |
| } |
| |
| data = (int32_t)meta_shot_ext->shot.udm.ae.vendorSpecific[399]; |
| |
| if (data <= ENTRANCE_LOW_LUX) { |
| ALOGD("(%s[%d]): need skip frame for ae/awb stable(%d).", __FUNCTION__, __LINE__, data); |
| m_exynosCameraParameters->setFrameSkipCount(2); |
| } |
| m_checkFirstFrameLux = false; |
| } |
| |
| status_t ExynosCamera::m_copyMetaFrameToFrame(ExynosCameraFrame *srcframe, ExynosCameraFrame *dstframe, bool useDm, bool useUdm) |
| { |
| Mutex::Autolock lock(m_metaCopyLock); |
| int ret = 0; |
| |
| memset(m_tempshot, 0x00, sizeof(struct camera2_shot_ext)); |
| if(useDm) { |
| srcframe->getDynamicMeta(m_tempshot); |
| ret = dstframe->storeDynamicMeta(m_tempshot); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): storeDynamicMeta fail ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| } |
| |
| if(useUdm) { |
| srcframe->getUserDynamicMeta(m_tempshot); |
| ret = dstframe->storeUserDynamicMeta(m_tempshot); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): storeUserDynamicMeta fail ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| } |
| |
| return NO_ERROR; |
| } |
| |
| |
| #ifdef SAMSUNG_DEBLUR |
| void ExynosCamera::setUseDeblurCaptureOn(bool enable) |
| { |
| m_useDeblurCaptureOn = enable; |
| } |
| |
| bool ExynosCamera::getUseDeblurCaptureOn(void) |
| { |
| return m_useDeblurCaptureOn; |
| } |
| |
| bool ExynosCamera::m_deblurCaptureThreadFunc(void) |
| { |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| CLOGI("INFO(%s[%d]):", __FUNCTION__, __LINE__); |
| |
| int ret = 0; |
| int loop = false; |
| ExynosCameraFrame *newFrame = NULL; |
| ExynosCameraBuffer gscReprocessingBuffer1; |
| ExynosCameraBuffer gscReprocessingBuffer2; |
| |
| gscReprocessingBuffer1.index = -2; |
| gscReprocessingBuffer2.index = -2; |
| |
| int pipeId_gsc = 0; |
| int currentSeriesShotMode = 0; |
| |
| if (m_exynosCameraParameters->isReprocessing() == true) { |
| if (needGSCForCapture(getCameraId()) == true) { |
| pipeId_gsc = PIPE_GSC_REPROCESSING; |
| } else { |
| pipeId_gsc = (isOwnScc(getCameraId()) == true) ? PIPE_SCC_REPROCESSING : PIPE_ISP_REPROCESSING; |
| } |
| } else { |
| if (needGSCForCapture(getCameraId()) == true) { |
| pipeId_gsc = PIPE_GSC_PICTURE; |
| } else { |
| if (isOwnScc(getCameraId()) == true) { |
| pipeId_gsc = PIPE_SCC; |
| } else { |
| pipeId_gsc = PIPE_ISPC; |
| } |
| } |
| } |
| |
| ExynosCameraBufferManager *bufferMgr = NULL; |
| ret = m_getBufferManager(pipeId_gsc, &bufferMgr, DST_BUFFER_DIRECTION); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getBufferManager(SRC) fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId_gsc, ret); |
| return ret; |
| } |
| |
| CLOGI("INFO(%s[%d]):wait m_deblurCaptureQ output", __FUNCTION__, __LINE__); |
| ret = m_deblurCaptureQ->waitAndPopProcessQ(&newFrame); |
| if (ret < 0) { |
| CLOGW("WARN(%s[%d]):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| /* TODO: doing exception handling */ |
| goto CLEAN; |
| } |
| if (newFrame == NULL) { |
| CLOGE("ERR(%s[%d]):newFrame is NULL", __FUNCTION__, __LINE__); |
| goto CLEAN; |
| } |
| |
| if (m_jpegCounter.getCount() <= 0) { |
| CLOGD("DEBUG(%s[%d]): Picture canceled", __FUNCTION__, __LINE__); |
| goto CLEAN; |
| } |
| |
| CLOGI("INFO(%s[%d]):m_deblurCaptureQ output done", __FUNCTION__, __LINE__); |
| |
| if (m_deblur_firstFrame == NULL) { |
| CLOGI("INFO(%s[%d]): first", __FUNCTION__, __LINE__); |
| m_deblur_firstFrame = newFrame; |
| } else { |
| m_deblur_secondFrame = newFrame; |
| |
| if (getUseDeblurCaptureOn()) { |
| CLOGI("INFO(%s[%d]):second getUseDeblurCaptureOn(%d)", __FUNCTION__, __LINE__, getUseDeblurCaptureOn()); |
| /* Library */ |
| int pipeId_postPictureGsc = PIPE_GSC_REPROCESSING2; |
| int previewW = 0, previewH = 0, previewFormat = 0; |
| int pictureW = 0, pictureH = 0, pictureFormat = 0; |
| ExynosRect srcRect_postPicturegGsc, dstRect_postPicturegGsc; |
| float zoomRatio = m_exynosCameraParameters->getZoomRatio(0) / 1000; |
| |
| CLOGD("[Deblur](%s[%d]):-- Start Library --", __FUNCTION__, __LINE__); |
| ExynosCameraDurationTimer m_timer; |
| long long durationTime = 0; |
| |
| m_timer.start(); |
| |
| ret = m_deblur_firstFrame->getDstBuffer(pipeId_gsc, &gscReprocessingBuffer1); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId_gsc, ret); |
| goto CLEAN; |
| } |
| |
| ret = m_deblur_secondFrame->getDstBuffer(pipeId_gsc, &gscReprocessingBuffer2); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId_gsc, ret); |
| goto CLEAN; |
| } |
| |
| m_exynosCameraParameters->getPictureSize(&pictureW, &pictureH); |
| pictureFormat = m_exynosCameraParameters->getPictureFormat(); |
| |
| if(m_DeblurpluginHandle != NULL) { |
| UniPluginBufferData_t pluginData; |
| memset(&pluginData, 0, sizeof(UniPluginBufferData_t)); |
| pluginData.InBuffY = gscReprocessingBuffer1.addr[0]; |
| pluginData.InBuffU = gscReprocessingBuffer1.addr[0] + (pictureW * pictureH); |
| pluginData.InWidth = pictureW; |
| pluginData.InHeight = pictureH; |
| pluginData.InFormat = UNI_PLUGIN_FORMAT_NV21; |
| pluginData.Index = 0; |
| CLOGD("[Deblur](%s[%d]): Buffer1 Width: %d, Height: %d", __FUNCTION__, __LINE__, |
| pluginData.InWidth, pluginData.InHeight); |
| ret = uni_plugin_set(m_DeblurpluginHandle, |
| DEBLUR_PLUGIN_NAME, UNI_PLUGIN_INDEX_BUFFER_INFO, &pluginData); |
| if(ret < 0) { |
| CLOGE("[Deblur](%s[%d]): Deblur Plugin set UNI_PLUGIN_INDEX_BUFFER_INFO failed!!", |
| __FUNCTION__, __LINE__); |
| } |
| #if 0 |
| char filePath[70] = "/data/media/0/deblur_input1.yuv"; |
| dumpToFile((char *)filePath, |
| gscReprocessingBuffer1.addr[0], |
| (pictureW * pictureH * 3) / 2); |
| #endif |
| memset(&pluginData, 0, sizeof(UniPluginBufferData_t)); |
| pluginData.InBuffY = gscReprocessingBuffer2.addr[0]; |
| pluginData.InBuffU = gscReprocessingBuffer2.addr[0] + (pictureW * pictureH); |
| pluginData.InWidth = pictureW; |
| pluginData.InHeight = pictureH; |
| pluginData.InFormat = UNI_PLUGIN_FORMAT_NV21; |
| pluginData.Index = 1; |
| CLOGD("[Deblur](%s[%d]): Buffer2 Width: %d, Height: %d", __FUNCTION__, __LINE__, |
| pluginData.InWidth, pluginData.InHeight); |
| ret = uni_plugin_set(m_DeblurpluginHandle, |
| DEBLUR_PLUGIN_NAME, UNI_PLUGIN_INDEX_BUFFER_INFO, &pluginData); |
| if(ret < 0) { |
| CLOGE("[Deblur](%s[%d]): Deblur Plugin set UNI_PLUGIN_INDEX_BUFFER_INFO failed!!", |
| __FUNCTION__, __LINE__); |
| } |
| #if 0 |
| char filePath2[70] = "/data/media/0/deblur_input2.yuv"; |
| dumpToFile((char *)filePath2, |
| gscReprocessingBuffer2.addr[0], |
| (pictureW * pictureH * 3) / 2); |
| #endif |
| UniPluginExtraBufferInfo_t extraData; |
| memset(&extraData, 0, sizeof(UniPluginExtraBufferInfo_t)); |
| |
| struct camera2_dm *dm = new struct camera2_dm; |
| memset(dm, 0, sizeof(camera2_dm)); |
| |
| m_deblur_firstFrame->getDynamicMeta(dm); |
| extraData.iso[0] = dm->sensor.sensitivity; |
| extraData.exposureTime.num = 1; |
| if (dm->sensor.exposureTime != 0) |
| extraData.exposureTime.den = (uint32_t) 1e9 / dm->sensor.exposureTime; |
| else |
| extraData.exposureTime.num = 0; |
| CLOGD("[Deblur](%s[%d]): ISO: %d, exposure: %d/%d", __FUNCTION__, __LINE__, |
| extraData.iso[0], extraData.exposureTime.num, extraData.exposureTime.den); |
| ret = uni_plugin_set(m_DeblurpluginHandle, |
| DEBLUR_PLUGIN_NAME, UNI_PLUGIN_INDEX_EXTRA_BUFFER_INFO, &extraData); |
| if(ret < 0) { |
| CLOGE("[Deblur](%s[%d]): Deblur Plugin set UNI_PLUGIN_INDEX_EXTRA_BUFFER_INFO failed!!", __FUNCTION__, __LINE__); |
| } |
| |
| delete dm; |
| |
| ret = uni_plugin_process(m_DeblurpluginHandle); |
| if(ret < 0) { |
| CLOGE("[Deblur](%s[%d]): Deblur Plugin process failed!!", __FUNCTION__, __LINE__); |
| } |
| #if 0 |
| char filePath3[70] = "/data/media/0/deblur_output2.yuv"; |
| dumpToFile((char *)filePath3, |
| gscReprocessingBuffer2.addr[0], |
| (pictureW * pictureH * 3) / 2); |
| #endif |
| } |
| m_timer.stop(); |
| durationTime = m_timer.durationMsecs(); |
| CLOGD("[Deblur](%s[%d]):duration time(%5d msec)", __FUNCTION__, __LINE__, (int)durationTime); |
| CLOGD("[Deblur](%s[%d]):-- end Library --", __FUNCTION__, __LINE__); |
| |
| if (m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_POSTVIEW_FRAME)) { |
| m_exynosCameraParameters->setIsThumbnailCallbackOn(true); |
| } |
| |
| if (m_exynosCameraParameters->getIsThumbnailCallbackOn()) { |
| CLOGD("POSTVIEW callback start, m_postPictureGscThread run (%s)(%d) pipe(%d)", |
| __FUNCTION__, __LINE__, pipeId_postPictureGsc); |
| |
| int retry1 = 0; |
| do { |
| ret = -1; |
| retry1++; |
| if (m_postPictureGscBufferMgr->getNumOfAvailableBuffer() > 0) { |
| ret = m_setupEntity(pipeId_postPictureGsc, m_deblur_secondFrame, &gscReprocessingBuffer2, NULL); |
| } else { |
| /* wait available SCC buffer */ |
| usleep(WAITING_TIME); |
| } |
| if (retry1 % 10 == 0) |
| CLOGW("WRAN(%s[%d]):retry setupEntity for GSC", __FUNCTION__, __LINE__); |
| } while(ret < 0 && retry1 < (TOTAL_WAITING_TIME/WAITING_TIME)); |
| |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail, pipeId(%d), retry(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId_postPictureGsc, retry1, ret); |
| goto CLEAN; |
| } |
| |
| m_exynosCameraParameters->getPreviewSize(&previewW, &previewH); |
| m_exynosCameraParameters->getPictureSize(&pictureW, &pictureH); |
| pictureFormat = m_exynosCameraParameters->getPictureFormat(); |
| previewFormat = m_exynosCameraParameters->getPreviewFormat(); |
| |
| CLOGD("DEBUG(%s):size preview(%d, %d,format:%d)picture(%d, %d,format:%d)", __FUNCTION__, |
| previewW, previewH, previewFormat, pictureW, pictureH, pictureFormat); |
| |
| srcRect_postPicturegGsc.x = 0; |
| srcRect_postPicturegGsc.y = 0; |
| srcRect_postPicturegGsc.w = pictureW; |
| srcRect_postPicturegGsc.h = pictureH; |
| srcRect_postPicturegGsc.fullW = pictureW; |
| srcRect_postPicturegGsc.fullH = pictureH; |
| srcRect_postPicturegGsc.colorFormat = HAL_PIXEL_FORMAT_2_V4L2_PIX(HAL_PIXEL_FORMAT_YCrCb_420_SP); |
| dstRect_postPicturegGsc.x = 0; |
| dstRect_postPicturegGsc.y = 0; |
| dstRect_postPicturegGsc.w = previewW; |
| dstRect_postPicturegGsc.h = previewH; |
| dstRect_postPicturegGsc.fullW = previewW; |
| dstRect_postPicturegGsc.fullH = previewH; |
| dstRect_postPicturegGsc.colorFormat = HAL_PIXEL_FORMAT_2_V4L2_PIX(HAL_PIXEL_FORMAT_YCrCb_420_SP); |
| |
| ret = getCropRectAlign(srcRect_postPicturegGsc.w, srcRect_postPicturegGsc.h, |
| previewW, previewH, |
| &srcRect_postPicturegGsc.x, &srcRect_postPicturegGsc.y, |
| &srcRect_postPicturegGsc.w, &srcRect_postPicturegGsc.h, |
| 2, 2, 0, zoomRatio); |
| |
| ret = m_deblur_secondFrame->setSrcRect(pipeId_postPictureGsc, &srcRect_postPicturegGsc); |
| ret = m_deblur_secondFrame->setDstRect(pipeId_postPictureGsc, &dstRect_postPicturegGsc); |
| |
| CLOGD("DEBUG(%s):size (%d, %d, %d, %d %d %d)", __FUNCTION__, |
| srcRect_postPicturegGsc.x, srcRect_postPicturegGsc.y, srcRect_postPicturegGsc.w, |
| srcRect_postPicturegGsc.h, srcRect_postPicturegGsc.fullW, srcRect_postPicturegGsc.fullH); |
| CLOGD("DEBUG(%s):size (%d, %d, %d, %d %d %d)", __FUNCTION__, |
| dstRect_postPicturegGsc.x, dstRect_postPicturegGsc.y, dstRect_postPicturegGsc.w, |
| dstRect_postPicturegGsc.h, dstRect_postPicturegGsc.fullW, dstRect_postPicturegGsc.fullH); |
| |
| /* push frame to GSC pipe */ |
| m_pictureFrameFactory->setOutputFrameQToPipe(dstPostPictureGscQ, pipeId_postPictureGsc); |
| m_pictureFrameFactory->pushFrameToPipe(&m_deblur_secondFrame, pipeId_postPictureGsc); |
| |
| ret = m_postPictureGscThread->run(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):couldn't run m_postPictureGscThread, ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto CLEAN; |
| } |
| } |
| |
| m_postPictureQ->pushProcessQ(&m_deblur_secondFrame); |
| m_deblur_secondFrame = NULL; |
| } else { |
| CLOGI("INFO(%s[%d]):second getUseDeblurCaptureOn(%d)", __FUNCTION__, __LINE__, getUseDeblurCaptureOn()); |
| ret = m_deblur_firstFrame->getDstBuffer(pipeId_gsc, &gscReprocessingBuffer1); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId_gsc, ret); |
| goto CLEAN; |
| } |
| |
| ret = m_deblur_secondFrame->getDstBuffer(pipeId_gsc, &gscReprocessingBuffer2); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId_gsc, ret); |
| goto CLEAN; |
| } |
| |
| /* put GSC buffer */ |
| ret = m_putBuffers(bufferMgr, gscReprocessingBuffer2.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):bufferMgr->putBuffers() fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId_gsc, ret); |
| goto CLEAN; |
| } |
| |
| if (m_deblur_secondFrame != NULL) { |
| m_deblur_secondFrame->printEntity(); |
| m_deblur_secondFrame->frameUnlock(); |
| ret = m_removeFrameFromList(&m_postProcessList, m_deblur_secondFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):remove frame from processList fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| |
| CLOGD("DEBUG(%s[%d]): Picture frame delete(%d)", __FUNCTION__, __LINE__, m_deblur_secondFrame->getFrameCount()); |
| m_deblur_secondFrame->decRef(); |
| m_frameMgr->deleteFrame(m_deblur_secondFrame); |
| m_deblur_secondFrame = NULL; |
| } |
| } |
| |
| /* put GSC 1st buffer */ |
| ret = m_putBuffers(bufferMgr, gscReprocessingBuffer1.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):bufferMgr->putBuffers() fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId_gsc, ret); |
| goto CLEAN; |
| } |
| |
| if (m_deblur_firstFrame != NULL) { |
| m_deblur_firstFrame->printEntity(); |
| m_deblur_firstFrame->frameUnlock(); |
| ret = m_removeFrameFromList(&m_postProcessList, m_deblur_firstFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):remove frame from processList fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| |
| CLOGD("DEBUG(%s[%d]): Picture frame delete(%d)", __FUNCTION__, __LINE__, m_deblur_firstFrame->getFrameCount()); |
| m_deblur_firstFrame->decRef(); |
| m_frameMgr->deleteFrame(m_deblur_firstFrame); |
| m_deblur_firstFrame = NULL; |
| } |
| } |
| |
| CLEAN: |
| |
| return loop; |
| } |
| |
| bool ExynosCamera::m_detectDeblurCaptureThreadFunc(void) |
| { |
| #ifdef DEBUG |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| #endif |
| int32_t previewFormat = 0; |
| status_t ret = NO_ERROR; |
| ExynosCameraBuffer postgscReprocessingBuffer; |
| ExynosCameraBufferManager *bufferMgr = NULL; |
| int gscPipe = PIPE_GSC_REPROCESSING3; |
| int loop = false; |
| |
| postgscReprocessingBuffer.index = -2; |
| |
| CLOGD("DEBUG(%s[%d]):-- IN --", __FUNCTION__, __LINE__); |
| |
| /* wait GSC */ |
| CLOGV("INFO(%s[%d]):wait GSC output pipe(%d)", __FUNCTION__, __LINE__); |
| ret = m_detectDeblurCaptureQ->waitAndPopProcessQ(&postgscReprocessingBuffer); |
| CLOGD("INFO(%s[%d]):GSC output done pipe(%d)", __FUNCTION__, __LINE__); |
| if (ret < 0) { |
| CLOGE("ERR(%s)(%d):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| /* TODO: doing exception handling */ |
| goto CLEAN; |
| } |
| |
| m_getBufferManager(gscPipe, &bufferMgr, SRC_BUFFER_DIRECTION); |
| |
| /* Library */ |
| CLOGD("DEBUG(%s[%d]):-- wait Library --", __FUNCTION__, __LINE__); |
| usleep(40000); |
| CLOGD("DEBUG(%s[%d]):-- end Library --", __FUNCTION__, __LINE__); |
| |
| #if 1 |
| setUseDeblurCaptureOn(true); |
| #else |
| setUseDeblurCaptureOn(false); |
| #endif |
| |
| CLOGD("DEBUG(%s[%d]):--OUT--", __FUNCTION__, __LINE__); |
| |
| CLEAN: |
| |
| if (postgscReprocessingBuffer.index != -2) |
| m_putBuffers(bufferMgr, postgscReprocessingBuffer.index); |
| |
| return loop; |
| } |
| #endif |
| |
| #ifdef SAMSUNG_LLS_DEBLUR |
| bool ExynosCamera::m_LDCaptureThreadFunc(void) |
| { |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| CLOGI("[LDC](%s[%d]):", __FUNCTION__, __LINE__); |
| |
| int ret = 0; |
| int loop = false; |
| ExynosCameraFrame *newFrame = NULL; |
| ExynosCameraBuffer gscReprocessingBuffer; |
| int pipeId_gsc = 0; |
| int pipeId_postPictureGsc = PIPE_GSC_REPROCESSING2; |
| int previewW = 0, previewH = 0, previewFormat = 0; |
| int pictureW = 0, pictureH = 0, pictureFormat = 0; |
| ExynosRect srcRect_postPicturegGsc, dstRect_postPicturegGsc; |
| float zoomRatio = m_exynosCameraParameters->getZoomRatio(0) / 1000; |
| int retry1 = 0; |
| ExynosCameraDurationTimer m_timer; |
| long long durationTime = 0; |
| |
| gscReprocessingBuffer.index = -2; |
| |
| if (m_exynosCameraParameters->isReprocessing() == true) { |
| if (needGSCForCapture(getCameraId()) == true) { |
| pipeId_gsc = PIPE_GSC_REPROCESSING; |
| } else { |
| pipeId_gsc = (isOwnScc(getCameraId()) == true) ? PIPE_SCC_REPROCESSING : PIPE_ISP_REPROCESSING; |
| } |
| } else { |
| if (needGSCForCapture(getCameraId()) == true) { |
| pipeId_gsc = PIPE_GSC_PICTURE; |
| } else { |
| if (isOwnScc(getCameraId()) == true) { |
| pipeId_gsc = PIPE_SCC; |
| } else { |
| pipeId_gsc = PIPE_ISPC; |
| } |
| } |
| } |
| |
| ExynosCameraBufferManager *bufferMgr = NULL; |
| ret = m_getBufferManager(pipeId_gsc, &bufferMgr, DST_BUFFER_DIRECTION); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getBufferManager(SRC) fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId_gsc, ret); |
| return ret; |
| } |
| |
| CLOGI("INFO(%s[%d]):wait m_deblurCaptureQ output", __FUNCTION__, __LINE__); |
| ret = m_LDCaptureQ->waitAndPopProcessQ(&newFrame); |
| if (ret < 0) { |
| CLOGW("WARN(%s[%d]):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| /* TODO: doing exception handling */ |
| goto CLEAN; |
| } |
| |
| if (newFrame == NULL) { |
| CLOGE("ERR(%s[%d]):newFrame is NULL", __FUNCTION__, __LINE__); |
| goto CLEAN; |
| } |
| |
| if (m_jpegCounter.getCount() <= 0) { |
| CLOGD("DEBUG(%s[%d]): Picture canceled", __FUNCTION__, __LINE__); |
| goto CLEAN; |
| } |
| |
| ret = newFrame->getDstBuffer(pipeId_gsc, &gscReprocessingBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId_gsc, ret); |
| goto CLEAN; |
| } |
| |
| m_LDBufIndex[m_LDCaptureCount] = gscReprocessingBuffer.index; |
| m_LDCaptureCount++; |
| |
| CLOGI("[LDC](%s[%d]):m_deblurCaptureQ output done m_LDCaptureCount(%d) index(%d)", |
| __FUNCTION__, __LINE__, m_LDCaptureCount, gscReprocessingBuffer.index); |
| |
| /* Library */ |
| CLOGD("[LDC](%s[%d]):-- Start Library --", __FUNCTION__, __LINE__); |
| m_timer.start(); |
| if (m_LLSpluginHandle != NULL) { |
| int totalCount = 0; |
| UNI_PLUGIN_OPERATION_MODE opMode = UNI_PLUGIN_OP_END; |
| |
| int llsMode = m_exynosCameraParameters->getLDCaptureLLSValue(); |
| switch(llsMode) { |
| case LLS_LEVEL_MULTI_MERGE_2: |
| case LLS_LEVEL_MULTI_MERGE_INDICATOR_2: |
| totalCount = 2; |
| opMode = UNI_PLUGIN_OP_COMPOSE_IMAGE; |
| break; |
| case LLS_LEVEL_MULTI_MERGE_3: |
| case LLS_LEVEL_MULTI_MERGE_INDICATOR_3: |
| totalCount = 3; |
| opMode = UNI_PLUGIN_OP_COMPOSE_IMAGE; |
| break; |
| case LLS_LEVEL_MULTI_MERGE_4: |
| case LLS_LEVEL_MULTI_MERGE_INDICATOR_4: |
| totalCount = 4; |
| opMode = UNI_PLUGIN_OP_COMPOSE_IMAGE; |
| break; |
| case LLS_LEVEL_MULTI_PICK_2: |
| totalCount = 2; |
| opMode = UNI_PLUGIN_OP_SELECT_IMAGE; |
| break; |
| case LLS_LEVEL_MULTI_PICK_3: |
| totalCount = 3; |
| opMode = UNI_PLUGIN_OP_SELECT_IMAGE; |
| break; |
| case LLS_LEVEL_MULTI_PICK_4: |
| totalCount = 4; |
| opMode = UNI_PLUGIN_OP_SELECT_IMAGE; |
| break; |
| default: |
| CLOGE("[LDC](%s[%d]): Wrong LLS mode has been get!!", __FUNCTION__, __LINE__); |
| goto CLEAN; |
| } |
| |
| /* First shot */ |
| if (m_LDCaptureCount == 1) { |
| ret = uni_plugin_init(m_LLSpluginHandle); |
| if (ret < 0) { |
| CLOGE("[LDC](%s[%d]): LLS Plugin init failed!!", __FUNCTION__, __LINE__); |
| } |
| |
| CLOGD("[LDC](%s[%d]): Set capture num: %d", __FUNCTION__, __LINE__, totalCount); |
| ret = uni_plugin_set(m_LLSpluginHandle, |
| LLS_PLUGIN_NAME, UNI_PLUGIN_INDEX_TOTAL_BUFFER_NUM, &totalCount); |
| if (ret < 0) { |
| CLOGE("[LDC](%s[%d]): LLS Plugin set UNI_PLUGIN_INDEX_TOTAL_BUFFER_NUM failed!!", __FUNCTION__, __LINE__); |
| } |
| |
| CLOGD("[LDC](%s[%d]): Set capture mode: %d", __FUNCTION__, __LINE__, opMode); |
| ret = uni_plugin_set(m_LLSpluginHandle, |
| LLS_PLUGIN_NAME, UNI_PLUGIN_INDEX_OPERATION_MODE, &opMode); |
| if (ret < 0) { |
| CLOGE("[LDC](%s[%d]): LLS Plugin set UNI_PLUGIN_INDEX_OPERATION_MODE failed!!", __FUNCTION__, __LINE__); |
| } |
| |
| UniPluginCameraInfo_t cameraInfo; |
| cameraInfo.CameraType = (UNI_PLUGIN_CAMERA_TYPE)getCameraId(); |
| cameraInfo.SensorType = (UNI_PLUGIN_SENSOR_TYPE)m_cameraSensorId; |
| CLOGD("[LDC](%s[%d]): Set camera info: %d:%d", __FUNCTION__, __LINE__, |
| cameraInfo.CameraType, cameraInfo.SensorType); |
| ret = uni_plugin_set(m_LLSpluginHandle, |
| LLS_PLUGIN_NAME, UNI_PLUGIN_INDEX_CAMERA_INFO, &cameraInfo); |
| if (ret < 0) { |
| CLOGE("[LDC](%s[%d]): LLS Plugin set UNI_PLUGIN_INDEX_CAMERA_INFO failed!!", __FUNCTION__, __LINE__); |
| } |
| |
| struct camera2_udm *udm = new struct camera2_udm; |
| |
| if (udm != NULL) { |
| UniPluginExtraBufferInfo_t extraData; |
| memset(&extraData, 0, sizeof(UniPluginExtraBufferInfo_t)); |
| memset(udm, 0x00, sizeof(struct camera2_udm)); |
| newFrame->getUserDynamicMeta(udm); |
| extraData.brightnessValue.num = udm->ae.vendorSpecific[5]; |
| extraData.brightnessValue.den = 256; |
| /* short shutter speed(us) */ |
| extraData.shutterSpeed[0].num = udm->ae.vendorSpecific[390]; |
| extraData.shutterSpeed[0].den = 1000000; |
| /* long shutter speed(us) */ |
| extraData.shutterSpeed[1].num = udm->ae.vendorSpecific[392]; |
| extraData.shutterSpeed[1].den = 1000000; |
| /* short ISO */ |
| extraData.iso[0] = udm->ae.vendorSpecific[391]; |
| /* long ISO */ |
| extraData.iso[1] = udm->ae.vendorSpecific[393]; |
| extraData.DRCstrength = udm->ae.vendorSpecific[394]; |
| ret = uni_plugin_set(m_LLSpluginHandle, |
| LLS_PLUGIN_NAME, UNI_PLUGIN_INDEX_EXTRA_BUFFER_INFO, &extraData); |
| if(ret < 0) { |
| CLOGE("[LDC](%s[%d]): LLS Plugin set UNI_PLUGIN_INDEX_EXTRA_BUFFER_INFO failed!!", __FUNCTION__, __LINE__); |
| } |
| |
| delete udm; |
| } |
| } |
| |
| UniPluginBufferData_t pluginData; |
| memset(&pluginData, 0, sizeof(UniPluginBufferData_t)); |
| m_exynosCameraParameters->getPictureSize(&pictureW, &pictureH); |
| pluginData.InBuffY = gscReprocessingBuffer.addr[0]; |
| pluginData.InBuffU = gscReprocessingBuffer.addr[0] + (pictureW * pictureH); |
| pluginData.InWidth = pictureW; |
| pluginData.InHeight = pictureH; |
| pluginData.InFormat = UNI_PLUGIN_FORMAT_NV21; |
| #if 0 |
| char filePath[100] = {'\0',}; |
| sprintf(filePath, "/data/media/0/LLS_input_%d.yuv", m_LDCaptureCount); |
| dumpToFile((char *)filePath, |
| gscReprocessingBuffer.addr[0], |
| (pictureW * pictureH * 3) / 2); |
| #endif |
| CLOGD("[LDC](%s[%d]): Set buffer info, Width: %d, Height: %d", __FUNCTION__, __LINE__, |
| pluginData.InWidth, pluginData.InHeight); |
| ret = uni_plugin_set(m_LLSpluginHandle, |
| LLS_PLUGIN_NAME, UNI_PLUGIN_INDEX_BUFFER_INFO, &pluginData); |
| if (ret < 0) { |
| CLOGE("[LDC](%s[%d]): LLS Plugin set UNI_PLUGIN_INDEX_BUFFER_INFO failed!!", __FUNCTION__, __LINE__); |
| } |
| |
| /* Last shot */ |
| if (m_LDCaptureCount == totalCount) { |
| ret = uni_plugin_process(m_LLSpluginHandle); |
| if (ret < 0) { |
| CLOGE("[LDC](%s[%d]): LLS Plugin process failed!!", __FUNCTION__, __LINE__); |
| } |
| |
| UTstr debugData; |
| debugData.data = new unsigned char[LLS_EXIF_SIZE]; |
| |
| ret = uni_plugin_get(m_LLSpluginHandle, |
| LLS_PLUGIN_NAME, UNI_PLUGIN_INDEX_DEBUG_INFO, &debugData); |
| CLOGD("[LDC](%s[%d]): Debug buffer size: %d", __FUNCTION__, __LINE__, debugData.size); |
| m_exynosCameraParameters->setLLSdebugInfo(debugData.data, debugData.size); |
| |
| if (debugData.data != NULL) |
| delete []debugData.data; |
| |
| ret = uni_plugin_deinit(m_LLSpluginHandle); |
| if (ret < 0) { |
| CLOGE("[LDC](%s[%d]): LLS Plugin deinit failed!!", __FUNCTION__, __LINE__); |
| } |
| } |
| } |
| m_timer.stop(); |
| durationTime = m_timer.durationMsecs(); |
| CLOGD("[LDC](%s[%d]):duration time(%5d msec)", __FUNCTION__, __LINE__, (int)durationTime); |
| CLOGD("[LDC](%s[%d]):-- end Library --", __FUNCTION__, __LINE__); |
| |
| if (m_LDCaptureCount < m_exynosCameraParameters->getLDCaptureCount()) { |
| if (newFrame != NULL) { |
| newFrame->printEntity(); |
| newFrame->frameUnlock(); |
| ret = m_removeFrameFromList(&m_postProcessList, newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):remove frame from processList fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| |
| CLOGD("DEBUG(%s[%d]): Picture frame delete(%d)", __FUNCTION__, __LINE__, newFrame->getFrameCount()); |
| newFrame->decRef(); |
| m_frameMgr->deleteFrame(newFrame); |
| newFrame = NULL; |
| } |
| goto CLEAN; |
| } |
| |
| if (m_exynosCameraParameters->msgTypeEnabled(CAMERA_MSG_POSTVIEW_FRAME)) { |
| m_exynosCameraParameters->setIsThumbnailCallbackOn(true); |
| } |
| |
| if (m_exynosCameraParameters->getIsThumbnailCallbackOn()) { |
| CLOGD("[LDC](%s[%d]): POSTVIEW callback start, m_postPictureGscThread run(%d)", |
| __FUNCTION__, __LINE__ , pipeId_postPictureGsc); |
| |
| do { |
| ret = -1; |
| retry1++; |
| if (m_postPictureGscBufferMgr->getNumOfAvailableBuffer() > 0) { |
| ret = m_setupEntity(pipeId_postPictureGsc, newFrame, &gscReprocessingBuffer, NULL); |
| } else { |
| /* wait available SCC buffer */ |
| usleep(WAITING_TIME); |
| } |
| if (retry1 % 10 == 0) |
| CLOGW("WRAN(%s[%d]):retry setupEntity for GSC", __FUNCTION__, __LINE__); |
| } while(ret < 0 && retry1 < (TOTAL_WAITING_TIME/WAITING_TIME)); |
| |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail, pipeId(%d), retry(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId_postPictureGsc, retry1, ret); |
| goto CLEAN; |
| } |
| |
| m_exynosCameraParameters->getPreviewSize(&previewW, &previewH); |
| m_exynosCameraParameters->getPictureSize(&pictureW, &pictureH); |
| pictureFormat = m_exynosCameraParameters->getPictureFormat(); |
| previewFormat = m_exynosCameraParameters->getPreviewFormat(); |
| |
| CLOGD("[LDC](%s):size preview(%d, %d,format:%d)picture(%d, %d,format:%d)", __FUNCTION__, |
| previewW, previewH, previewFormat, pictureW, pictureH, pictureFormat); |
| |
| srcRect_postPicturegGsc.x = 0; |
| srcRect_postPicturegGsc.y = 0; |
| srcRect_postPicturegGsc.w = pictureW; |
| srcRect_postPicturegGsc.h = pictureH; |
| srcRect_postPicturegGsc.fullW = pictureW; |
| srcRect_postPicturegGsc.fullH = pictureH; |
| srcRect_postPicturegGsc.colorFormat = HAL_PIXEL_FORMAT_2_V4L2_PIX(HAL_PIXEL_FORMAT_YCrCb_420_SP); |
| dstRect_postPicturegGsc.x = 0; |
| dstRect_postPicturegGsc.y = 0; |
| dstRect_postPicturegGsc.w = previewW; |
| dstRect_postPicturegGsc.h = previewH; |
| dstRect_postPicturegGsc.fullW = previewW; |
| dstRect_postPicturegGsc.fullH = previewH; |
| dstRect_postPicturegGsc.colorFormat = HAL_PIXEL_FORMAT_2_V4L2_PIX(HAL_PIXEL_FORMAT_YCrCb_420_SP); |
| |
| ret = getCropRectAlign(srcRect_postPicturegGsc.w, srcRect_postPicturegGsc.h, |
| previewW, previewH, |
| &srcRect_postPicturegGsc.x, &srcRect_postPicturegGsc.y, |
| &srcRect_postPicturegGsc.w, &srcRect_postPicturegGsc.h, |
| 2, 2, 0, zoomRatio); |
| |
| ret = newFrame->setSrcRect(pipeId_postPictureGsc, &srcRect_postPicturegGsc); |
| ret = newFrame->setDstRect(pipeId_postPictureGsc, &dstRect_postPicturegGsc); |
| |
| CLOGD("[LDC](%s):size (%d, %d, %d, %d %d %d)", __FUNCTION__, |
| srcRect_postPicturegGsc.x, srcRect_postPicturegGsc.y, srcRect_postPicturegGsc.w, |
| srcRect_postPicturegGsc.h, srcRect_postPicturegGsc.fullW, srcRect_postPicturegGsc.fullH); |
| CLOGD("[LDC](%s):size (%d, %d, %d, %d %d %d)", __FUNCTION__, |
| dstRect_postPicturegGsc.x, dstRect_postPicturegGsc.y, dstRect_postPicturegGsc.w, |
| dstRect_postPicturegGsc.h, dstRect_postPicturegGsc.fullW, dstRect_postPicturegGsc.fullH); |
| |
| /* push frame to GSC pipe */ |
| m_pictureFrameFactory->setOutputFrameQToPipe(dstPostPictureGscQ, pipeId_postPictureGsc); |
| m_pictureFrameFactory->pushFrameToPipe(&newFrame, pipeId_postPictureGsc); |
| |
| ret = m_postPictureGscThread->run(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):couldn't run m_postPictureGscThread, ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto CLEAN; |
| } |
| } |
| |
| m_postPictureQ->pushProcessQ(&newFrame); |
| |
| for (int i = 0; i < m_exynosCameraParameters->getLDCaptureCount() - 1; i++) { |
| /* put GSC 1st buffer */ |
| ret = m_putBuffers(bufferMgr, m_LDBufIndex[i]); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):bufferMgr->putBuffers() fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId_gsc, ret); |
| } |
| } |
| |
| CLEAN: |
| int waitCount = 15; |
| if (m_LDCaptureCount == m_exynosCameraParameters->getLDCaptureCount()) { |
| waitCount = 0; |
| } |
| |
| while (m_LDCaptureQ->getSizeOfProcessQ() == 0 && 0 < waitCount) { |
| usleep(10000); |
| waitCount--; |
| } |
| |
| if (m_LDCaptureQ->getSizeOfProcessQ()) { |
| CLOGD("[LDC](%s[%d]):m_LDCaptureThread thread will run again. m_LDCaptureQ size(%d)", |
| __func__, __LINE__, m_LDCaptureQ->getSizeOfProcessQ()); |
| loop = true; |
| } |
| |
| return loop; |
| } |
| |
| #endif |
| |
| }; /* namespace android */ |