| /* |
| ** |
| ** Copyright 2015, 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" |
| |
| namespace android { |
| |
| #ifdef MONITOR_LOG_SYNC |
| uint32_t ExynosCamera::cameraSyncLogId = 0; |
| #endif |
| |
| ExynosCamera::ExynosCamera(int cameraId, camera_device_t *dev) |
| { |
| ExynosCameraActivityUCTL *uctlMgr = NULL; |
| |
| BUILD_DATE(); |
| |
| checkAndroidVersion(); |
| |
| m_cameraId = cameraId; |
| m_dev = dev; |
| |
| initialize(); |
| } |
| |
| void ExynosCamera::initialize() |
| { |
| CLOGI("INFO(%s[%d]): -IN-", __FUNCTION__, __LINE__); |
| int ret = 0; |
| |
| ExynosCameraActivityUCTL *uctlMgr = NULL; |
| memset(m_name, 0x00, sizeof(m_name)); |
| |
| #ifdef SAMSUNG_TN_FEATURE |
| m_use_companion = isCompanion(m_cameraId); |
| #endif |
| m_parameters = new ExynosCamera1Parameters(m_cameraId); |
| CLOGD("DEBUG(%s):Parameters(Id=%d) created", __FUNCTION__, m_cameraId); |
| |
| #ifndef SAMSUNG_TN_FEATURE |
| m_use_companion = m_parameters->isCompanion(m_cameraId); |
| #endif |
| m_parameters->setHalVersion(IS_HAL_VER_1_0); |
| |
| m_exynosCameraActivityControl = m_parameters->getActivityControl(); |
| |
| m_previewFrameFactory = NULL; |
| m_reprocessingFrameFactory = NULL; |
| /* vision */ |
| m_visionFrameFactory= NULL; |
| |
| m_ionAllocator = NULL; |
| m_grAllocator = NULL; |
| m_mhbAllocator = NULL; |
| |
| m_frameMgr = NULL; |
| |
| 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"); |
| m_createInternalBufferManager(&m_vraBufferMgr, "VRA_BUF"); |
| |
| /* 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"); |
| m_createInternalBufferManager(&m_thumbnailBufferMgr, "THUMBNAIL_BUF"); |
| |
| /* preview Buffer */ |
| m_scpBufferMgr = NULL; |
| m_createInternalBufferManager(&m_previewCallbackBufferMgr, "PREVIEW_CB_BUF"); |
| m_createInternalBufferManager(&m_highResolutionCallbackBufferMgr, "HIGH_RESOLUTION_CB_BUF"); |
| m_fdCallbackHeap = NULL; |
| |
| /* recording Buffer */ |
| m_recordingCallbackHeap = NULL; |
| m_createInternalBufferManager(&m_recordingBufferMgr, "REC_BUF"); |
| |
| m_createThreads(); |
| |
| 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; |
| #ifdef STK_PICTURE |
| dstStkPictureQ = new frame_queue_t; |
| #endif |
| 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_previewQ = new frame_queue_t; |
| m_previewQ->setWaitTime(500000000); |
| |
| m_vraThreadQ = new frame_queue_t; |
| m_vraThreadQ->setWaitTime(500000000); |
| m_vraGscDoneQ = new frame_queue_t; |
| m_vraGscDoneQ->setWaitTime(500000000); |
| m_vraPipeDoneQ = new frame_queue_t; |
| m_vraPipeDoneQ->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); |
| for(int i = 0 ; i < MAX_NUM_PIPES ; i++ ) { |
| m_mainSetupQ[i] = new frame_queue_t; |
| m_mainSetupQ[i]->setWaitTime(500000000); |
| } |
| m_jpegCallbackQ = new jpeg_callback_queue_t; |
| m_postviewCallbackQ = new postview_callback_queue_t; |
| |
| 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); |
| #ifdef STK_PICTURE |
| dstStkPictureQ->setWaitTime(1000000000); |
| #endif |
| dstJpegReprocessingQ->setWaitTime(500000000); |
| /* vision */ |
| m_pipeFrameVisionDoneQ->setWaitTime(2000000000); |
| |
| m_jpegCallbackQ->setWaitTime(1000000000); |
| m_postviewCallbackQ->setWaitTime(1000000000); |
| |
| 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; |
| 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; |
| m_skipCount = 0; |
| |
| #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; |
| |
| 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_parameters->setIsFirstStartFlag(m_isFirstStart); |
| #ifdef RAWDUMP_CAPTURE |
| m_RawCaptureDumpQ = new frame_queue_t(m_RawCaptureDumpThread); |
| #endif |
| #ifdef RAWDUMP_CAPTURE |
| ExynosCameraActivitySpecialCapture *m_sCapture = m_exynosCameraActivityControl->getSpecialCaptureMgr(); |
| m_sCapture->resetRawCaptureFcount(); |
| #endif |
| |
| m_exynosconfig = NULL; |
| m_setConfigInform(); |
| |
| m_setFrameManager(); |
| |
| |
| /* HACK Reset Preview Flag*/ |
| m_resetPreview = false; |
| |
| m_dynamicSccCount = 0; |
| m_previewBufferCount = NUM_PREVIEW_BUFFERS; |
| |
| /* HACK for CTS2.0 */ |
| m_oldPreviewW = 0; |
| m_oldPreviewH = 0; |
| |
| #ifdef FIRST_PREVIEW_TIME_CHECK |
| m_flagFirstPreviewTimerOn = false; |
| #endif |
| |
| /* init infomation of fd orientation*/ |
| m_parameters->setDeviceOrientation(0); |
| uctlMgr = m_exynosCameraActivityControl->getUCTLMgr(); |
| if (uctlMgr != NULL) |
| uctlMgr->setDeviceRotation(m_parameters->getFdOrientation()); |
| #ifdef MONITOR_LOG_SYNC |
| m_syncLogDuration = 0; |
| #endif |
| vendorSpecificConstructor(m_cameraId, m_dev); |
| |
| m_callbackCookie = 0; |
| m_fliteFrameCount = 0; |
| m_3aa_ispFrameCount = 0; |
| m_ispFrameCount = 0; |
| m_sccFrameCount = 0; |
| m_scpFrameCount = 0; |
| m_vraRunningCount = 0; |
| m_lastRecordingTimeStamp = 0; |
| m_recordingStartTimeStamp = 0; |
| m_fdCallbackHeap = 0; |
| m_burstSaveTimerTime = 0; |
| m_burstDuration = 0; |
| m_burstInitFirst = 0; |
| m_burstRealloc = 0; |
| m_displayPreviewToggle = 0; |
| m_hdrSkipedFcount = 0; |
| m_curMinFps = 0; |
| m_visionFps = 0; |
| m_visionAe = 0; |
| m_hackForAlignment = 0; |
| m_recordingFrameSkipCount = 0; |
| m_faceDetected = false; |
| m_flagThreadStop = false; |
| m_isNeedAllocPictureBuffer = false; |
| m_isCancelBurstCapture = false; |
| m_isTryStopFlash = false; |
| m_notifyCb = NULL; |
| m_dataCb = NULL; |
| m_dataCbTimestamp = NULL; |
| m_getMemoryCb = NULL; |
| m_previewWindow = NULL; |
| m_initFrameFactory(); |
| |
| m_tempshot = new struct camera2_shot_ext; |
| m_fdmeta_shot = new struct camera2_shot_ext; |
| m_meta_shot = new struct camera2_shot_ext; |
| |
| #ifdef DEBUG_RAWDUMP |
| isRawDumpOngoing = false; |
| #endif |
| } |
| |
| 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_sensor_buffers = (getCameraId() == CAMERA_ID_BACK) ? NUM_SENSOR_BUFFERS : FRONT_NUM_SENSOR_BUFFERS; |
| 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_vra_buffers = NUM_VRA_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_sensor_buffers = (getCameraId() == CAMERA_ID_BACK) ? FPS60_NUM_NUM_SENSOR_BUFFERS : FPS60_FRONT_NUM_SENSOR_BUFFERS; |
| 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_vra_buffers = FPS60_NUM_VRA_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_sensor_buffers = (getCameraId() == CAMERA_ID_BACK) ? FPS120_NUM_NUM_SENSOR_BUFFERS : FPS120_FRONT_NUM_SENSOR_BUFFERS; |
| 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_vra_buffers = FPS120_NUM_VRA_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_120].bufInfo.num_preview_buffers = (FPS120_NUM_PREVIEW_BUFFERS > MAX_BUFFERS) ? MAX_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; |
| #ifdef SUPPORT_HIGH_SPEED_240FPS |
| /* Config HIGH_SPEED 240 buffer & pipe info */ |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_240].bufInfo.num_sensor_buffers = (getCameraId() == CAMERA_ID_BACK) ? FPS240_NUM_NUM_SENSOR_BUFFERS : FPS240_FRONT_NUM_SENSOR_BUFFERS; |
| 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_vra_buffers = FPS240_NUM_VRA_BUFFERS; |
| exynosConfig.info[CONFIG_MODE::HIGHSPEED_240].bufInfo.num_preview_buffers = (FPS240_NUM_PREVIEW_BUFFERS > MAX_BUFFERS) ? MAX_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 |
| #endif |
| |
| m_parameters->setConfig(&exynosConfig); |
| |
| m_exynosconfig = m_parameters->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_parameters->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_vraThread = new mainCameraThread(this, &ExynosCamera::m_vraThreadFunc, "vraThread"); |
| CLOGD("DEBUG(%s[%d]):recordingThread created", __FUNCTION__, __LINE__); |
| |
| 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__); |
| |
| /* 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__); |
| |
| } |
| |
| status_t ExynosCamera::m_setupFrameFactory(void) |
| { |
| CLOGI("INFO(%s[%d]): -IN-", __FUNCTION__, __LINE__); |
| |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| |
| status_t ret = NO_ERROR; |
| |
| if (m_parameters->getVisionMode() == true) { |
| /* about vision */ |
| if( m_frameFactory[FRAME_FACTORY_TYPE_VISION] == NULL) { |
| m_frameFactory[FRAME_FACTORY_TYPE_VISION] = new ExynosCameraFrameFactoryVision(m_cameraId, m_parameters); |
| 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 { |
| /* about preview */ |
| if (m_parameters->getDualMode() == true) { |
| m_previewFrameFactory = m_frameFactory[FRAME_FACTORY_TYPE_DUAL_PREVIEW]; |
| } else if (m_parameters->getTpuEnabledMode() == true) { |
| if (m_parameters->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_parameters->is3aaIspOtf() == true) |
| m_previewFrameFactory = m_frameFactory[FRAME_FACTORY_TYPE_3AA_ISP_OTF]; |
| else |
| m_previewFrameFactory = m_frameFactory[FRAME_FACTORY_TYPE_3AA_ISP_M2M]; |
| } |
| |
| /* 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_parameters->isReprocessing() == true) { |
| int numOfReprocessingFactory = m_parameters->getNumOfReprocessingFactory(); |
| |
| for (int i = FRAME_FACTORY_TYPE_REPROCESSING; i < numOfReprocessingFactory + FRAME_FACTORY_TYPE_REPROCESSING; i++) { |
| if (m_frameFactory[i] != NULL && m_frameFactory[i]->isCreated() == false) { |
| CLOGD("DEBUG(%s[%d]):setupFrameFactory pushProcessQ(%d)", __FUNCTION__, __LINE__, FRAME_FACTORY_TYPE_REPROCESSING); |
| m_frameFactoryQ->pushProcessQ(&m_frameFactory[i]); |
| } |
| } |
| } |
| } |
| |
| /* |
| * 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 ExynosCameraFrameFactory3aaIspM2M(m_cameraId, m_parameters); |
| m_frameFactory[FRAME_FACTORY_TYPE_3AA_ISP_M2M] = factory; |
| /* hack : for dual */ |
| if (getCameraId() == CAMERA_ID_FRONT) { |
| factory = new ExynosCameraFrameFactoryFront(m_cameraId, m_parameters); |
| m_frameFactory[FRAME_FACTORY_TYPE_DUAL_PREVIEW] = factory; |
| } else { |
| factory = new ExynosCameraFrameFactory3aaIspM2M(m_cameraId, m_parameters); |
| m_frameFactory[FRAME_FACTORY_TYPE_DUAL_PREVIEW] = factory; |
| } |
| |
| factory = new ExynosCameraFrameFactory3aaIspM2MTpu(m_cameraId, m_parameters); |
| m_frameFactory[FRAME_FACTORY_TYPE_3AA_ISP_M2M_TPU] = factory; |
| |
| factory = new ExynosCameraFrameFactory3aaIspOtf(m_cameraId, m_parameters); |
| m_frameFactory[FRAME_FACTORY_TYPE_3AA_ISP_OTF] = factory; |
| |
| factory = new ExynosCameraFrameFactory3aaIspOtfTpu(m_cameraId, m_parameters); |
| m_frameFactory[FRAME_FACTORY_TYPE_3AA_ISP_OTF_TPU] = factory; |
| |
| factory = new ExynosCameraFrameReprocessingFactory(m_cameraId, m_parameters); |
| m_frameFactory[FRAME_FACTORY_TYPE_REPROCESSING] = factory; |
| |
| factory = new ExynosCameraFrameReprocessingFactoryNV21(m_cameraId, m_parameters); |
| m_frameFactory[FRAME_FACTORY_TYPE_REPROCESSING_NV21] = 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; |
| |
| m_stopCompanion(); |
| |
| if (m_frameMgr != NULL) { |
| m_frameMgr->stop(); |
| } |
| |
| /* release all framefactory */ |
| m_deinitFrameFactory(); |
| |
| if (m_parameters != NULL) { |
| delete m_parameters; |
| m_parameters = NULL; |
| CLOGD("DEBUG(%s):Parameters(Id=%d) destroyed", __FUNCTION__, m_cameraId); |
| } |
| |
| /* free all buffers */ |
| m_releaseBuffers(); |
| |
| 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; |
| } |
| |
| #ifdef STK_PICTURE |
| if (dstStkPictureQ != NULL) { |
| delete dstStkPictureQ; |
| dstStkPictureQ = NULL; |
| } |
| #endif |
| |
| if (dstJpegReprocessingQ != NULL) { |
| delete dstJpegReprocessingQ; |
| dstJpegReprocessingQ = NULL; |
| } |
| |
| if (m_postPictureQ != NULL) { |
| delete m_postPictureQ; |
| m_postPictureQ = NULL; |
| } |
| |
| if (m_jpegCallbackQ != NULL) { |
| delete m_jpegCallbackQ; |
| m_jpegCallbackQ = NULL; |
| } |
| |
| if (m_postviewCallbackQ != NULL) { |
| delete m_postviewCallbackQ; |
| m_postviewCallbackQ = NULL; |
| } |
| |
| if (m_facedetectQ != NULL) { |
| delete m_facedetectQ; |
| m_facedetectQ = NULL; |
| } |
| |
| if (m_previewQ != NULL) { |
| delete m_previewQ; |
| m_previewQ = NULL; |
| } |
| |
| if (m_vraThreadQ != NULL) { |
| delete m_vraThreadQ; |
| m_vraThreadQ = NULL; |
| } |
| |
| if (m_vraGscDoneQ != NULL) { |
| delete m_vraGscDoneQ; |
| m_vraGscDoneQ = NULL; |
| } |
| |
| if (m_vraPipeDoneQ != NULL) { |
| delete m_vraPipeDoneQ; |
| m_vraPipeDoneQ = 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__); |
| } |
| |
| 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_vraBufferMgr != NULL) { |
| delete m_vraBufferMgr; |
| m_vraBufferMgr = NULL; |
| CLOGD("DEBUG(%s[%d]):BufferManager(vraBufferMgr) destroyed", __FUNCTION__, __LINE__); |
| } |
| |
| 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_jpegBufferMgr != NULL) { |
| delete m_jpegBufferMgr; |
| m_jpegBufferMgr = NULL; |
| CLOGD("DEBUG(%s):BufferManager(jpegBufferMgr) destroyed", __FUNCTION__); |
| } |
| |
| if (m_thumbnailBufferMgr != NULL) { |
| delete m_thumbnailBufferMgr; |
| m_thumbnailBufferMgr = NULL; |
| CLOGD("DEBUG(%s[%d]):BufferManager(thumbnailBufferMgr) destroyed", __FUNCTION__, __LINE__); |
| } |
| |
| 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__); |
| } |
| |
| 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; |
| } |
| |
| vendorSpecificDestructor(); |
| |
| 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)); |
| } |
| |
| 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_parameters) { |
| CLOGV("INFO(%s[%d]): enable Msg (%x)", __FUNCTION__, __LINE__, msgType); |
| m_parameters->enableMsgType(msgType); |
| } |
| } |
| |
| void ExynosCamera::disableMsgType(int32_t msgType) |
| { |
| if (m_parameters) { |
| CLOGV("INFO(%s[%d]): disable Msg (%x)", __FUNCTION__, __LINE__, msgType); |
| m_parameters->disableMsgType(msgType); |
| } |
| } |
| |
| bool ExynosCamera::msgTypeEnabled(int32_t msgType) |
| { |
| bool IsEnabled = false; |
| |
| if (m_parameters) { |
| CLOGV("INFO(%s[%d]): Msg type enabled (%x)", __FUNCTION__, __LINE__, msgType); |
| IsEnabled = m_parameters->msgTypeEnabled(msgType); |
| } |
| |
| return IsEnabled; |
| } |
| |
| 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_parameters != NULL && |
| (m_parameters->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; |
| } |
| |
| 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_parameters != NULL) { |
| if (m_parameters->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__); |
| /* The received native_handle must be closed */ |
| /* return; */ |
| } |
| |
| struct VideoNativeHandleMetadata *releaseMetadata = (struct VideoNativeHandleMetadata *) opaque; |
| |
| if (releaseMetadata == NULL) { |
| CLOGW("WARN(%s[%d]):releaseMetadata is NULL", __FUNCTION__, __LINE__); |
| return; |
| } |
| |
| 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_parameters != NULL) { |
| m_parameters->setIsFirstStartFlag(m_isFirstStart); |
| } |
| |
| CLEAN: |
| if (releaseHandle != NULL) { |
| native_handle_close(releaseHandle); |
| native_handle_delete(releaseHandle); |
| } |
| |
| if (releaseMetadata != NULL) { |
| m_releaseRecordingCallbackHeap(releaseMetadata); |
| } |
| |
| return; |
| } |
| |
| status_t ExynosCamera::autoFocus() |
| { |
| CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__); |
| |
| if (m_parameters != NULL) { |
| if (m_parameters->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_parameters != NULL) { |
| if (m_parameters->getFocusMode() == FOCUS_MODE_AUTO) { |
| CLOGI("INFO(%s[%d]) ae awb lock", __FUNCTION__, __LINE__); |
| m_parameters->m_setAutoExposureLock(true); |
| m_parameters->m_setAutoWhiteBalanceLock(true); |
| } |
| } |
| #endif |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCamera::cancelAutoFocus() |
| { |
| CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__); |
| |
| if (m_parameters != NULL) { |
| if (m_parameters->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; |
| |
| #if 0 // not used. |
| if (m_parameters != NULL) { |
| if (m_parameters->getFocusMode() == FOCUS_MODE_AUTO) { |
| CLOGI("INFO(%s[%d]) ae awb unlock", __FUNCTION__, __LINE__); |
| m_parameters->m_setAutoExposureLock(false); |
| m_parameters->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::cancelPicture() |
| { |
| CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__); |
| |
| if (m_parameters != NULL) { |
| if (m_parameters->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; |
| } |
| } |
| |
| /* |
| m_takePictureCounter.clearCount(); |
| m_reprocessingCounter.clearCount(); |
| m_pictureCounter.clearCount(); |
| m_jpegCounter.clearCount(); |
| */ |
| |
| return NO_ERROR; |
| } |
| |
| CameraParameters ExynosCamera::getParameters() const |
| { |
| CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__); |
| |
| return m_parameters->getParameters(); |
| } |
| |
| int ExynosCamera::getMaxNumDetectedFaces(void) |
| { |
| return m_parameters->getMaxNumDetectedFaces(); |
| } |
| |
| bool ExynosCamera::m_startFaceDetection(bool toggle) |
| { |
| CLOGD("DEBUG(%s[%d]) toggle : %d", __FUNCTION__, __LINE__, toggle); |
| |
| if (toggle == true) { |
| m_parameters->setFdEnable(true); |
| m_parameters->setFdMode(FACEDETECT_MODE_FULL); |
| if (m_parameters->isMcscVraOtf() == false) |
| m_previewFrameFactory->startThread(PIPE_VRA); |
| } else { |
| m_parameters->setFdEnable(false); |
| m_parameters->setFdMode(FACEDETECT_MODE_OFF); |
| if (m_parameters->isMcscVraOtf() == false) { |
| m_vraThread->requestExit(); |
| |
| if (m_vraThreadQ != NULL) |
| m_clearList(m_vraThreadQ); |
| |
| if (m_vraGscDoneQ != NULL) |
| m_clearList(m_vraGscDoneQ); |
| |
| if (m_vraPipeDoneQ != NULL) |
| m_clearList(m_vraPipeDoneQ); |
| } |
| } |
| |
| 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 |
| |
| #ifdef ENABLE_FDAF_WITH_FD |
| /* Enable FD-AF according to FD condition */ |
| if(m_parameters->getFdEnable() == 0) |
| #else |
| /* Block FD-AF except for special shot modes */ |
| if(m_parameters->getShotMode() == SHOT_MODE_BEAUTY_FACE || |
| m_parameters->getShotMode() == SHOT_MODE_SELFIE_ALARM) |
| #endif |
| { |
| 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; |
| } |
| |
| 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; |
| } |
| |
| 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) { |
| CLOGE("ERR(%s[%d]):m_facedetectQ skipped QSize(%d)", __FUNCTION__, __LINE__, count); |
| if (newFrame != NULL) { |
| 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; |
| } |
| |
| 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 (m_parameters->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_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 maxThumbnailW = 0, maxThumbnailH = 0; |
| int planeCount = 1; |
| int minBufferCount = 1; |
| int maxBufferCount = 1; |
| int numOfReprocessingFactory = 0; |
| int pictureFormat = m_parameters->getHwPictureFormat(); |
| bool needMmap = false; |
| 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]; |
| ExynosCameraBufferManager *mcscBufferManager[MAX_NODE]; |
| for (int i = 0; i < MAX_NODE; i++) { |
| taaBufferManager[i] = NULL; |
| ispBufferManager[i] = NULL; |
| mcscBufferManager[i] = NULL; |
| } |
| |
| if (m_zslPictureEnabled == true) { |
| CLOGD("DEBUG(%s[%d]): zsl picture is already initialized", __FUNCTION__, __LINE__); |
| return NO_ERROR; |
| } |
| |
| if (m_parameters->isReprocessing() == true) { |
| if( m_parameters->getHighSpeedRecording() ) { |
| m_parameters->getHwSensorSize(&hwPictureW, &hwPictureH); |
| CLOGI("(%s):HW Picture(HighSpeed) width x height = %dx%d", __FUNCTION__, hwPictureW, hwPictureH); |
| } else { |
| m_parameters->getMaxPictureSize(&hwPictureW, &hwPictureH); |
| CLOGI("(%s):HW Picture width x height = %dx%d", __FUNCTION__, hwPictureW, hwPictureH); |
| } |
| |
| m_parameters->getMaxThumbnailSize(&maxThumbnailW, &maxThumbnailH); |
| |
| if (m_parameters->isUseYuvReprocessingForThumbnail() == true) |
| needMmap = true; |
| else |
| needMmap = false; |
| |
| if (m_parameters->isHWFCEnabled() == true |
| && m_parameters->getHighResolutionCallbackMode() == false) { |
| allocMode = BUFFER_MANAGER_ALLOCATION_ATONCE; |
| } |
| |
| 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_parameters->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, needMmap); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_sccReprocessingBufferMgr m_allocBuffers(minBufferCount=%d, maxBufferCount=%d) fail", |
| __FUNCTION__, __LINE__, minBufferCount, maxBufferCount); |
| return ret; |
| } |
| |
| if (m_parameters->getUsePureBayerReprocessing() == true) { |
| ret = m_setReprocessingBuffer(); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_setReprocessing Buffer fail", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| } |
| |
| /* Reprocessing Thumbnail Buffer */ |
| if (pictureFormat == V4L2_PIX_FMT_NV21M) { |
| planeCount = 3; |
| planeSize[0] = maxThumbnailW * maxThumbnailH; |
| planeSize[1] = maxThumbnailW * maxThumbnailH / 2; |
| } else { |
| planeCount = 2; |
| planeSize[0] = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(pictureFormat), maxThumbnailW, maxThumbnailH); |
| } |
| minBufferCount = 1; |
| maxBufferCount = m_exynosconfig->current->bufInfo.num_picture_buffers; |
| type = EXYNOS_CAMERA_BUFFER_ION_CACHED_TYPE; |
| |
| ret = m_allocBuffers(m_thumbnailBufferMgr, planeCount, planeSize, bytesPerLine, |
| minBufferCount, maxBufferCount, type, allocMode, true, needMmap); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):m_thumbnailBufferMgr m_allocBuffers(minBufferCount=%d, maxBufferCount=%d) fail", |
| __FUNCTION__, __LINE__, minBufferCount, maxBufferCount); |
| return ret; |
| } |
| } |
| |
| numOfReprocessingFactory = m_parameters->getNumOfReprocessingFactory(); |
| |
| for (int i = FRAME_FACTORY_TYPE_REPROCESSING; i < numOfReprocessingFactory + FRAME_FACTORY_TYPE_REPROCESSING; i++) { |
| if (m_frameFactory[i]->isCreated() == false) { |
| ret = m_frameFactory[i]->create(); |
| if (ret < 0) { |
| CLOGE("ERR(%s):m_reprocessingFrameFactory->create() failed", __FUNCTION__); |
| return ret; |
| } |
| |
| } |
| |
| if (i == FRAME_FACTORY_TYPE_REPROCESSING) { |
| m_reprocessingFrameFactory = m_frameFactory[i]; |
| 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_parameters->isReprocessing3aaIspOTF() == false) { |
| taaBufferManager[m_frameFactory[i]->getNodeType(PIPE_3AA_REPROCESSING)] = m_bayerBufferMgr; |
| taaBufferManager[m_frameFactory[i]->getNodeType(PIPE_3AP_REPROCESSING)] = m_ispReprocessingBufferMgr; |
| } else { |
| taaBufferManager[m_frameFactory[i]->getNodeType(PIPE_3AA_REPROCESSING)] = m_bayerBufferMgr; |
| taaBufferManager[m_frameFactory[i]->getNodeType(PIPE_ISPC_REPROCESSING)] = m_sccReprocessingBufferMgr; |
| |
| taaBufferManager[OUTPUT_NODE] = m_bayerBufferMgr; |
| taaBufferManager[CAPTURE_NODE] = m_sccReprocessingBufferMgr; |
| } |
| #endif |
| |
| ret = m_frameFactory[i]->setBufferManagerToPipe(taaBufferManager, PIPE_3AA_REPROCESSING); |
| if (ret < 0) { |
| CLOGE("ERR(%s):m_reprocessingFrameFactory->setBufferManagerToPipe() failed", __FUNCTION__); |
| return ret; |
| } |
| |
| ispBufferManager[m_frameFactory[i]->getNodeType(PIPE_ISP_REPROCESSING)] = m_ispReprocessingBufferMgr; |
| ispBufferManager[m_frameFactory[i]->getNodeType(PIPE_ISPC_REPROCESSING)] = m_sccReprocessingBufferMgr; |
| |
| ret = m_frameFactory[i]->setBufferManagerToPipe(ispBufferManager, PIPE_ISP_REPROCESSING); |
| if (ret < 0) { |
| CLOGE("ERR(%s):m_reprocessingFrameFactory->setBufferManagerToPipe() failed", __FUNCTION__); |
| return ret; |
| } |
| |
| mcscBufferManager[m_frameFactory[i]->getNodeType(PIPE_MCSC_REPROCESSING)] = m_sccBufferMgr; |
| mcscBufferManager[m_frameFactory[i]->getNodeType(PIPE_MCSC0_REPROCESSING)] = m_sccReprocessingBufferMgr; |
| mcscBufferManager[m_frameFactory[i]->getNodeType(PIPE_HWFC_JPEG_SRC_REPROCESSING)] = m_sccReprocessingBufferMgr; |
| mcscBufferManager[m_frameFactory[i]->getNodeType(PIPE_HWFC_THUMB_SRC_REPROCESSING)] = m_thumbnailBufferMgr; |
| mcscBufferManager[m_frameFactory[i]->getNodeType(PIPE_HWFC_JPEG_DST_REPROCESSING)] = m_jpegBufferMgr; |
| mcscBufferManager[m_frameFactory[i]->getNodeType(PIPE_HWFC_THUMB_DST_REPROCESSING)] = m_thumbnailBufferMgr; |
| |
| ret = m_frameFactory[i]->setBufferManagerToPipe(mcscBufferManager, PIPE_MCSC_REPROCESSING); |
| if (ret < 0) { |
| CLOGE("ERR(%s):m_reprocessingFrameFactory->setBufferManagerToPipe() failed", __FUNCTION__); |
| return ret; |
| } |
| |
| ret = m_frameFactory[i]->initPipes(); |
| if (ret < 0) { |
| CLOGE("ERR(%s):m_reprocessingFrameFactory->initPipes() failed", __FUNCTION__); |
| return ret; |
| } |
| |
| ret = m_frameFactory[i]->preparePipes(); |
| if (ret < 0) { |
| CLOGE("ERR(%s):m_reprocessingFrameFactory preparePipe fail", __FUNCTION__); |
| return ret; |
| } |
| |
| /* stream on pipes */ |
| ret = m_frameFactory[i]->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; |
| } |
| |
| 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; |
| int retrycount = 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; |
| } |
| |
| /* HACK : |
| * Prevent to deliver the changed size with per-frame control |
| * before the H/W size setting is finished. |
| */ |
| if (m_parameters->getPreviewSizeChanged() == true) { |
| CLOGI("INFO(%s[%d]):Preview size is changed. Skip to generate new frame", |
| __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; |
| } |
| |
| do { |
| ret = generateFrame(m_3aa_ispFrameCount, &newframe); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):generateFrame fail", __FUNCTION__, __LINE__); |
| usleep(100); |
| } |
| if(++retrycount >= 10) { |
| goto func_exit; |
| } |
| } while((ret < 0) && (retrycount < 10)); |
| |
| 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_parameters->is3aaIspOtf() == true) { |
| if (m_parameters->isMcscVraOtf() == true) |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, pipeId_3AA); |
| |
| if (m_parameters->getTpuEnabledMode() == true) |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, pipeId_DIS); |
| } else { |
| m_previewFrameFactory->setFrameDoneQToPipe(m_pipeFrameDoneQ, pipeId_3AA); |
| |
| if (m_parameters->getTpuEnabledMode() == true) { |
| m_previewFrameFactory->setFrameDoneQToPipe(m_pipeFrameDoneQ, pipeId_ISP); |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, pipeId_DIS); |
| } else { |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, pipeId_ISP); |
| } |
| } |
| |
| if (m_parameters->isMcscVraOtf() == false) { |
| m_previewFrameFactory->setFrameDoneQToPipe(m_pipeFrameDoneQ, PIPE_3AA); |
| m_previewFrameFactory->setOutputFrameQToPipe(m_pipeFrameDoneQ, PIPE_VRA); |
| } |
| |
| 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; |
| |
| 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; |
| } |
| |
| if (m_bayerBufferMgr->getNumOfAvailableBuffer() > 0) { |
| 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++; |
| } |
| |
| 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 (m_bayerBufferMgr->getAllocatedBufferCount() - PIPE_3AC_PREPARE_COUNT |
| // < m_bayerBufferMgr->getNumOfAvailableBuffer()); |
| } while (0 < m_bayerBufferMgr->getNumOfAvailableBuffer()); |
| } |
| |
| func_exit: |
| if( frame != NULL ) { |
| frame->decRef(); |
| m_frameMgr->deleteFrame(frame);; |
| } |
| |
| /* |
| if (m_mainSetupQ[INDEX(pipeId)]->getSizeOfProcessQ() <= 0) |
| loop = false; |
| */ |
| |
| 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 ) { |
| ret = frame->getDstBuffer(pipeId, &resultBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| ret = m_setupEntity(pipeId, newframe, NULL, &resultBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail", __FUNCTION__, __LINE__); |
| } |
| ret = newframe->getDstBuffer(pipeId, &resultBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| } else { |
| ret = m_setupEntity(pipeId, newframe); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail", __FUNCTION__, __LINE__); |
| } |
| ret = newframe->getDstBuffer(pipeId, &resultBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| } |
| |
| /*check preview drop...*/ |
| ret = newframe->getDstBuffer(pipeId, &resultBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| 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_parameters->msgTypeEnabled(CAMERA_MSG_VIDEO_FRAME) |
| && m_parameters->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_parameters->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_parameters->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_parameters->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_parameters->isFlite3aaOtf() == true) { |
| ret = m_handlePreviewFrame(newFrame); |
| } else { |
| if (m_parameters->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; |
| } |
| |
| 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; |
| } |
| |
| 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_parameters->getPreviewFormat(); |
| |
| m_parameters->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_doZoomPrviewWithCSC(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; |
| int previewH, previewW; |
| int bufIndex = -1; |
| int waitCount = 0; |
| int scpNodeIndex = -1; |
| int srcNodeIndex = -1; |
| int srcFmt = -1; |
| |
| previewFormat = m_parameters->getHwPreviewFormat(); |
| m_parameters->getHwPreviewSize(&previewW, &previewH); |
| |
| /* To pass the CTS2.0 Test "CameraDeviceTest", |
| * When changing of preview size is happen consequently, |
| * Prevent to do the Pipe CSC dqbuf before the H/W size setting is finished. |
| */ |
| CLOGV("DEBUG(%s[%d]): getPreviewSizeChanged() : %d", |
| __FUNCTION__, __LINE__, m_parameters->getPreviewSizeChanged()); |
| |
| if (m_parameters->getPreviewSizeChanged() == true) { |
| CLOGW("INFO(%s[%d]):Preview size is changed. Skip to doZoomPrviewWithCSC", |
| __FUNCTION__, __LINE__); |
| return INVALID_OPERATION; |
| } |
| |
| if ((m_parameters->getPreviewSizeChanged() == false) && |
| (m_oldPreviewW != (unsigned)previewW) && |
| (m_oldPreviewH != (unsigned)previewH)) { |
| CLOGI("INFO(%s[%d]):HW Preview size is changed. Update size(%d x %d)", |
| __FUNCTION__, __LINE__, previewW, previewH); |
| |
| m_oldPreviewW = previewW; |
| m_oldPreviewH = previewH; |
| } |
| |
| /* get Scaler src Buffer Node Index*/ |
| if (m_parameters->getDualMode() != true) { |
| srcNodeIndex = m_previewFrameFactory->getNodeType(PIPE_SCP); |
| srcFmt = previewFormat; |
| scpNodeIndex = m_previewFrameFactory->getNodeType(PIPE_SCP); |
| } else { |
| srcFmt = previewFormat; |
| return true; |
| } |
| |
| /* 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)",__FUNCTION__, __LINE__, pipeId, ret); |
| return ret; |
| } |
| |
| /* getMetadata to get buffer size */ |
| meta = (struct camera2_stream*)srcBuf.addr[srcBuf.planeCount-1]; |
| if (meta == NULL) { |
| CLOGE("ERR(%s[%d]):srcBuf.addr is NULL, srcBuf.addr(0x%x)",__FUNCTION__, __LINE__, srcBuf.addr[srcBuf.planeCount-1]); |
| return INVALID_OPERATION; |
| } |
| |
| output = meta->output_crop_region; |
| |
| /* check scaler conditions( compare the crop size & format ) */ |
| if (output[2] == (unsigned)previewW && output[3] == (unsigned)previewH && srcFmt == previewFormat |
| #ifdef USE_PREVIEW_CROP_FOR_ROATAION |
| && m_parameters->getRotationProperty() != FORCE_PREVIEW_BUFFER_CROP_ROTATION_270 |
| #endif |
| ) { |
| /* HACK for CTS2.0 */ |
| m_oldPreviewW = previewW; |
| m_oldPreviewH = previewH; |
| |
| return ret; |
| } |
| |
| /* wait unitil get buffers */ |
| do { |
| dstBuf.index = -2; |
| waitCount++; |
| |
| if (m_scpBufferMgr->getNumOfAvailableBuffer() > 0) |
| m_scpBufferMgr->getBuffer(&bufIndex, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL, &dstBuf); |
| |
| if (dstBuf.index < 0) { |
| usleep(WAITING_TIME); |
| |
| if (waitCount % 20 == 0) { |
| CLOGW("WRN(%s[%d]):retry JPEG getBuffer(%d) m_zoomPreviwWithCscQ->getSizeOfProcessQ(%d)", |
| __FUNCTION__, __LINE__, bufIndex, m_zoomPreviwWithCscQ->getSizeOfProcessQ()); |
| m_scpBufferMgr->dump(); |
| } |
| } else { |
| break; |
| } |
| /* this will retry until 300msec */ |
| } while (waitCount < (TOTAL_WAITING_TIME / WAITING_TIME) && previewEnabled() == false); |
| |
| if (bufIndex == -1) { |
| m_scpBufferMgr->cancelBuffer(srcBuf.index); |
| CLOGE("ERR(%s[%d]):Failed to get the gralloc Buffer for GSC dstBuf ",__FUNCTION__, __LINE__); |
| return INVALID_OPERATION; |
| } |
| |
| /* 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; |
| |
| #ifdef USE_PREVIEW_CROP_FOR_ROATAION |
| if (m_parameters->getRotationProperty() == FORCE_PREVIEW_BUFFER_CROP_ROTATION_270) { |
| int old_width = srcRect.w; |
| if (srcRect.w > srcRect.h) { |
| srcRect.w = ALIGN_DOWN(srcRect.h*srcRect.h / srcRect.w, GSCALER_IMG_ALIGN); |
| srcRect.x = ALIGN_DOWN((old_width-srcRect.w) / 2, GSCALER_IMG_ALIGN); |
| } |
| } |
| #endif |
| |
| dstRect.x = 0; |
| dstRect.y = 0; |
| dstRect.w = previewW; |
| dstRect.h = previewH; |
| dstRect.fullW = previewW; |
| dstRect.fullH = previewH; |
| dstRect.colorFormat = previewFormat; |
| |
| CLOGV("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__, 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 = frame->setSrcRect(gscPipe, srcRect); |
| ret = frame->setDstRect(gscPipe, dstRect); |
| |
| ret = m_setupEntity(gscPipe, frame, &srcBuf, &dstBuf); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setupEntity fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, gscPipe, ret); |
| } |
| |
| #ifdef USE_PREVIEW_CROP_FOR_ROATAION |
| if (m_parameters->getRotationProperty() == FORCE_PREVIEW_BUFFER_CROP_ROTATION_270) { |
| ret = frame->setRotation(gscPipe, 270); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):setRotation(%d) fail", __FUNCTION__, __LINE__, 270); |
| ret = INVALID_OPERATION; |
| goto func_exit; |
| } |
| } |
| #endif |
| |
| m_previewFrameFactory->setOutputFrameQToPipe(m_zoomPreviwWithCscQ, gscPipe); |
| m_previewFrameFactory->pushFrameToPipe(&frame, gscPipe); |
| |
| /* wait GSC done */ |
| CLOGV("INFO(%s[%d]):wait GSC output", __FUNCTION__, __LINE__); |
| waitCount = 0; |
| |
| do { |
| ret = m_zoomPreviwWithCscQ->waitAndPopProcessQ(&frame); |
| 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 (frame == NULL) { |
| CLOGE("ERR(%s[%d]):frame is NULL", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| /* copy metadata src to dst*/ |
| memcpy(dstBuf.addr[dstBuf.planeCount-1],srcBuf.addr[srcBuf.planeCount-1], sizeof(struct camera2_stream)); |
| |
| if (m_parameters->getDualMode() == true && getCameraId() == CAMERA_ID_FRONT) { |
| /* in case of dual front path buffer returned frameSelector, do not return buffer. */ |
| } else { |
| m_scpBufferMgr->cancelBuffer(srcBuf.index); |
| } |
| |
| ret = frame->setDstBufferState(pipeId, ENTITY_BUFFER_STATE_REQUESTED, scpNodeIndex); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s): setDstBufferState state fail", __FUNCTION__); |
| return ret; |
| } |
| |
| ret = frame->setDstBuffer(pipeId, dstBuf, scpNodeIndex); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):setdst Buffer failed(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| |
| ret = frame->setDstBufferState(pipeId, ENTITY_BUFFER_STATE_COMPLETE, scpNodeIndex); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s): setDstBufferState state fail", __FUNCTION__); |
| return ret; |
| } |
| |
| func_exit: |
| |
| CLOGV("DEBUG(%s[%d]):--OUT--", __FUNCTION__, __LINE__); |
| |
| return ret; |
| } |
| |
| 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_parameters->getSeriesShotDuration(); |
| |
| m_burstPrePictureTimer.start(); |
| |
| if (m_parameters->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__, m_burstPrePictureTimerTime, 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; |
| #ifdef DEBUG_RAWDUMP |
| ExynosCameraBuffer bayerBuffer; |
| ExynosCameraBuffer pictureBuffer; |
| ExynosCameraFrame *inListFrame = NULL; |
| ExynosCameraFrame *bayerFrame = NULL; |
| #endif |
| int pipeId = 0; |
| int bufPipeId = 0; |
| bool isSrc = false; |
| int retryCount = 3; |
| |
| if (m_hdrEnabled) |
| retryCount = 15; |
| |
| #ifdef OIS_CAPTURE |
| if (m_parameters->getOISCaptureModeOn() == true) { |
| retryCount = 7; |
| } |
| #endif |
| |
| if (m_parameters->isOwnScc(getCameraId()) == true) |
| bufPipeId = PIPE_SCC; |
| else if (m_parameters->isUsing3acForIspc() == true) |
| bufPipeId = PIPE_3AC; |
| else |
| bufPipeId = PIPE_ISPC; |
| |
| if (m_parameters->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; |
| } |
| |
| if (m_parameters->getRecordingHint() == true |
| && m_parameters->isUsing3acForIspc() == true) |
| m_sccCaptureSelector->clearList(pipeId, false, m_previewFrameFactory->getNodeType(bufPipeId)); |
| |
| 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_parameters->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_parameters->getHighResolutionCallbackMode() == true) && |
| (m_highResolutionCallbackRunning == true)) |
| loop = true; |
| |
| if (m_reprocessingCounter.getCount() > 0) { |
| loop = true; |
| |
| } |
| |
| *pIsProcessed = true; |
| |
| #ifdef DEBUG_RAWDUMP |
| retryCount = 30; /* 200ms x 30 */ |
| bayerBuffer.index = -2; |
| isRawDumpOngoing = true; |
| |
| ret = newFrame->getDstBuffer(PIPE_FLITE, &bayerBuffer); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): getDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, PIPE_FLITE, ret); |
| } else { |
| if (m_parameters->checkBayerDumpEnable()) { |
| int sensorMaxW, sensorMaxH; |
| int sensorMarginW, sensorMarginH; |
| bool bRet; |
| char filePath[70]; |
| int fliteFcount = 0; |
| int pictureFcount = 0; |
| |
| camera2_shot_ext *shot_ext = NULL; |
| |
| if (m_parameters->isUsing3acForIspc() == true) { |
| ret = newFrame->getDstBuffer(PIPE_3AA, &pictureBuffer, |
| m_previewFrameFactory->getNodeType(PIPE_3AC)); |
| } else { |
| ret = newFrame->getDstBuffer(PIPE_3AA, &pictureBuffer, |
| m_previewFrameFactory->getNodeType(PIPE_ISPC)); |
| } |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): getDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, PIPE_3AA, ret); |
| } |
| |
| shot_ext = (camera2_shot_ext *)(bayerBuffer.addr[1]); |
| if (shot_ext != NULL) |
| fliteFcount = shot_ext->shot.dm.request.frameCount; |
| else |
| ALOGE("ERR(%s[%d]):fliteBayerBuffer is null", __FUNCTION__, __LINE__); |
| |
| shot_ext = NULL; |
| shot_ext = (camera2_shot_ext *)(pictureBuffer.addr[1]); |
| if (shot_ext != NULL) |
| pictureFcount = shot_ext->shot.dm.request.frameCount; |
| else |
| ALOGE("ERR(%s[%d]):PictureBuffer is null", __FUNCTION__, __LINE__); |
| |
| CLOGD("DEBUG(%s[%d]):bayer fcount(%d) picture fcount(%d)", |
| __FUNCTION__, __LINE__, fliteFcount, pictureFcount); |
| /* The driver frame count is used to check the match between the 3AA frame and the FLITE frame. |
| if the match fails then the bayer buffer does not correspond to the capture output and hence |
| not written to the file */ |
| if (fliteFcount == pictureFcount) { |
| memset(filePath, 0, sizeof(filePath)); |
| snprintf(filePath, sizeof(filePath), "/data/media/0/RawCapture%d_%d.raw",m_cameraId, pictureFcount); |
| |
| bRet = dumpToFile((char *)filePath, |
| bayerBuffer.addr[0], |
| bayerBuffer.size[0]); |
| if (bRet != true) |
| CLOGE("couldn't make a raw file"); |
| } |
| } |
| } |
| |
| isRawDumpOngoing = false; |
| #endif |
| 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_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_parameters->getPreviewSize(&cbPreviewW, &cbPreviewH); |
| previewFormat = m_parameters->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; |
| |
| if (m_parameters->isUseYuvReprocessing() == true) { |
| pipeId_scc = PIPE_MCSC_REPROCESSING; |
| pipeId_gsc = PIPE_GSC_REPROCESSING; |
| } else if (m_parameters->isUsing3acForIspc() == true) { |
| pipeId_scc = PIPE_3AA; |
| pipeId_gsc = PIPE_GSC_PICTURE; |
| } else { |
| pipeId_scc = (m_parameters->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_parameters->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_parameters->msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) { |
| /* get GSC src buffer */ |
| if (m_parameters->isUseYuvReprocessing() == true) { |
| ret = newFrame->getDstBuffer(pipeId_scc, &highResolutionCbBuffer, m_reprocessingFrameFactory->getNodeType(PIPE_MCSC0_REPROCESSING)); |
| } else if (m_parameters->isUsing3acForIspc() == true) |
| ret = newFrame->getDstBuffer(pipeId_scc, &sccReprocessingBuffer, m_previewFrameFactory->getNodeType(PIPE_3AC)); |
| else |
| ret = newFrame->getDstBuffer(pipeId_scc, &sccReprocessingBuffer, m_reprocessingFrameFactory->getNodeType(PIPE_SCC_REPROCESSING)); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", |
| __FUNCTION__, __LINE__, pipeId_scc, ret); |
| goto CLEAN; |
| } |
| |
| if (m_parameters->isUseYuvReprocessing() == false) { |
| 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; |
| } |
| |
| if (m_parameters->isUseYuvReprocessing() == false) { |
| /* 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__); |
| 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 */ |
| if (m_parameters->isUsing3acForIspc() == true) { |
| ret = newFrame->getDstBuffer(pipeId_scc, &sccReprocessingBuffer, m_previewFrameFactory->getNodeType(PIPE_3AC)); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId_scc, ret); |
| goto CLEAN; |
| } |
| ret = m_putBuffers(m_sccBufferMgr, sccReprocessingBuffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):put Buffer fail", __FUNCTION__, __LINE__); |
| } |
| } else { |
| ret = newFrame->getDstBuffer(pipeId_scc, &sccReprocessingBuffer, m_reprocessingFrameFactory->getNodeType(PIPE_SCC_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 (ret < 0) { |
| CLOGE("ERR(%s[%d]):put Buffer fail", __FUNCTION__, __LINE__); |
| } |
| } |
| } |
| |
| CLOGV("DEBUG(%s[%d]):high resolution preview callback", __FUNCTION__, __LINE__); |
| if (m_parameters->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); |
| |
| /* put high resolution callback buffer */ |
| if (m_parameters->isUseYuvReprocessing() == true) |
| ret = m_putBuffers(m_sccReprocessingBufferMgr, highResolutionCbBuffer.index); |
| else |
| ret = m_putBuffers(m_highResolutionCallbackBufferMgr, highResolutionCbBuffer.index); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_putBuffers fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId_gsc, ret); |
| goto CLEAN; |
| } |
| } else { |
| CLOGD("DEBUG(%s[%d]): Preview callback message disabled, skip callback", __FUNCTION__, __LINE__); |
| /* put SCC buffer */ |
| if (m_parameters->isUseYuvReprocessing() == true) { |
| ret = newFrame->getDstBuffer(pipeId_scc, &sccReprocessingBuffer, m_reprocessingFrameFactory->getNodeType(PIPE_MCSC0_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); |
| } else if (m_parameters->isUsing3acForIspc() == true) { |
| ret = newFrame->getDstBuffer(pipeId_scc, &sccReprocessingBuffer, m_previewFrameFactory->getNodeType(PIPE_3AC)); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):getDstBuffer fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, pipeId_scc, ret); |
| goto CLEAN; |
| } |
| ret = m_putBuffers(m_sccBufferMgr, sccReprocessingBuffer.index); |
| } else { |
| ret = newFrame->getDstBuffer(pipeId_scc, &sccReprocessingBuffer, m_reprocessingFrameFactory->getNodeType(PIPE_SCC_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 (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; |
| } |
| |
| if(m_flagThreadStop != true) { |
| if (m_highResolutionCallbackQ->getSizeOfProcessQ() > 0 || |
| m_parameters->getHighResolutionCallbackMode() == true) { |
| CLOGD("DEBUG(%s[%d]):highResolutionCallbackQ size(%d), highResolutionCallbackMode(%s), start again", |
| __FUNCTION__, __LINE__, |
| m_highResolutionCallbackQ->getSizeOfProcessQ(), |
| (m_parameters->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 (sccReprocessingBuffer.index != -2) |
| ret = m_putBuffers(m_sccReprocessingBufferMgr, sccReprocessingBuffer.index); |
| if (highResolutionCbBuffer.index != -2) |
| 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); |
| } |
| |
| ret = m_deleteFrame(&newFrame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):m_deleteFrame fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| } |
| |
| if(m_flagThreadStop != true) { |
| if (m_highResolutionCallbackQ->getSizeOfProcessQ() > 0 || |
| m_parameters->getHighResolutionCallbackMode() == true) { |
| CLOGD("DEBUG(%s[%d]):highResolutionCallbackQ size(%d), highResolutionCallbackMode(%s), start again", |
| __FUNCTION__, __LINE__, |
| m_highResolutionCallbackQ->getSizeOfProcessQ(), |
| (m_parameters->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_vraThreadFunc(void) |
| { |
| #ifdef DEBUG |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| #endif |
| |
| status_t ret = NO_ERROR; |
| int gscPipeId = PIPE_GSC_VRA; |
| int vraPipeId = PIPE_VRA; |
| |
| ExynosCameraFrame *gscFrame = NULL; |
| ExynosCameraFrame *gscDoneFrame = NULL; |
| ExynosCameraFrame *vraFrame = NULL; |
| ExynosCameraFrame *vraDoneFrame = NULL; |
| ExynosCameraBuffer srcBuf; |
| ExynosCameraBuffer dstBuf; |
| int vraWidth = 0, vraHeight = 0; |
| int dstBufIndex = -2; |
| int frameCount = -1; |
| |
| int waitCount = 0; |
| |
| struct camera2_stream *streamMeta = NULL; |
| uint32_t *mcscOutputCrop = NULL; |
| |
| ExynosRect srcRect, dstRect; |
| int32_t previewFormat = m_parameters->getHwPreviewFormat(); |
| m_parameters->getHwVraInputSize(&vraWidth, &vraHeight); |
| |
| /* Pop frame from MCSC output Q */ |
| CLOGV("INFO(%s[%d]):wait MCSC output", __FUNCTION__, __LINE__); |
| |
| ret = m_vraThreadQ->waitAndPopProcessQ(&gscFrame); |
| |
| if (m_flagThreadStop == true) |
| goto func_exit; |
| |
| if (ret != NO_ERROR) { |
| if (ret == TIMED_OUT) { |
| CLOGW("WARN(%s[%d]):wait timeout", __FUNCTION__, __LINE__); |
| } else { |
| CLOGE("ERR(%s[%d]):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| /* TODO: doing exception handling */ |
| } |
| goto func_exit; |
| } |
| |
| if (gscFrame == NULL) { |
| CLOGE("ERR(%s[%d]):gscFrame is NULL", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| frameCount = gscFrame->getFrameCount(); |
| CLOGV("INFO(%s[%d]):Get GSC frame for VRA, frameCount(%d)", __FUNCTION__, __LINE__, frameCount); |
| |
| m_vraRunningCount++; |
| |
| /* Get scaler source buffer */ |
| ret = gscFrame->getSrcBuffer(gscPipeId, &srcBuf); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):getSrcBuffer fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| /* TODO: doing exception handling */ |
| goto func_exit; |
| } |
| |
| /* Get scaler destination buffer */ |
| do { |
| waitCount++; |
| |
| if (m_vraBufferMgr->getNumOfAvailableBuffer() > 0) |
| m_vraBufferMgr->getBuffer(&dstBufIndex, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL, &dstBuf); |
| |
| if (dstBufIndex < 0) { |
| usleep(WAITING_TIME); |
| |
| if (waitCount % 20 == 0) { |
| CLOGW("WRN(%s[%d]):retry VRA getBuffer(%d)", __FUNCTION__, __LINE__, dstBufIndex); |
| m_scpBufferMgr->dump(); |
| } |
| } else { |
| break; |
| } |
| /* this will retry until 300msec */ |
| } while (waitCount < (TOTAL_WAITING_TIME / WAITING_TIME) && previewEnabled() == false); |
| |
| /* Get size from metadata */ |
| streamMeta = (struct camera2_stream*)srcBuf.addr[srcBuf.planeCount-1]; |
| if (streamMeta == NULL) { |
| CLOGE("ERR(%s[%d]):srcBuf.addr is NULL, srcBuf.addr(0x%x)",__FUNCTION__, __LINE__, srcBuf.addr[srcBuf.planeCount-1]); |
| goto func_exit; |
| } |
| |
| /* Set size to GSC frame */ |
| mcscOutputCrop = streamMeta->output_crop_region; |
| |
| srcRect.x = 0; |
| srcRect.y = 0; |
| srcRect.w = mcscOutputCrop[2]; |
| srcRect.h = mcscOutputCrop[3]; |
| srcRect.fullW = mcscOutputCrop[2]; |
| srcRect.fullH = mcscOutputCrop[3]; |
| srcRect.colorFormat = previewFormat; |
| |
| dstRect.x = 0; |
| dstRect.y = 0; |
| dstRect.w = vraWidth; |
| dstRect.h = vraHeight; |
| dstRect.fullW = vraWidth; |
| dstRect.fullH = vraHeight; |
| dstRect.colorFormat = m_parameters->getHwVraInputFormat(); |
| |
| ret = gscFrame->setSrcRect(gscPipeId, srcRect); |
| ret = gscFrame->setDstRect(gscPipeId, dstRect); |
| |
| ret = m_setupEntity(gscPipeId, gscFrame, &srcBuf, &dstBuf); |
| if (ret != NO_ERROR) { |
| CLOGE("ERR(%s[%d]):setupEntity fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, gscPipeId, ret); |
| } |
| |
| m_previewFrameFactory->setOutputFrameQToPipe(m_vraGscDoneQ, gscPipeId); |
| m_previewFrameFactory->pushFrameToPipe(&gscFrame, gscPipeId); |
| |
| /* Wait and Pop frame from GSC output Q */ |
| CLOGV("INFO(%s[%d]):wait GSC output", __FUNCTION__, __LINE__); |
| |
| waitCount = 0; |
| do { |
| ret = m_vraGscDoneQ->waitAndPopProcessQ(&gscDoneFrame); |
| waitCount++; |
| |
| if (m_flagThreadStop == true) { |
| if (m_vraRunningCount > 0) |
| m_vraRunningCount--; |
| return false; |
| } |
| } while (ret == TIMED_OUT && waitCount < 10); |
| |
| if (ret != NO_ERROR) |
| CLOGW("WARN(%s[%d]):GSC wait and pop error, ret(%d)", __FUNCTION__, __LINE__, ret); |
| |
| if (gscDoneFrame == NULL) { |
| CLOGE("ERR(%s[%d]):gscFrame is NULL", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| CLOGV("INFO(%s[%d]):Get frame from GSC Pipe, frameCount(%d)", __FUNCTION__, __LINE__, frameCount); |
| |
| vraFrame = m_previewFrameFactory->createNewFrameOnlyOnePipe(vraPipeId, frameCount); |
| |
| if (vraFrame != NULL) { |
| /* Set perframe size of VRA */ |
| camera2_node_group node_group_info; |
| memset(&node_group_info, 0x0, sizeof(camera2_node_group)); |
| |
| node_group_info.leader.request = 1; |
| node_group_info.leader.input.cropRegion[0] = 0; |
| node_group_info.leader.input.cropRegion[1] = 0; |
| node_group_info.leader.input.cropRegion[2] = vraWidth; |
| node_group_info.leader.input.cropRegion[3] = vraHeight; |
| 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]; |
| |
| vraFrame->storeNodeGroupInfo(&node_group_info, PERFRAME_INFO_VRA); |
| |
| /* Copy metadata frame to dst buffer */ |
| struct camera2_shot_ext shot_ext; |
| gscDoneFrame->getMetaData(&shot_ext); |
| memcpy(dstBuf.addr[dstBuf.planeCount-1], &shot_ext, sizeof(struct camera2_shot_ext)); |
| |
| /* Set FD bypass from parameters */ |
| shot_ext.fd_bypass = m_parameters->getFdEnable(); |
| switch (getCameraId()) { |
| case CAMERA_ID_FRONT: |
| /* HACK: Calibrate FD orientation */ |
| shot_ext.shot.uctl.scalerUd.orientation = (m_parameters->getDeviceOrientation() + FRONT_ROTATION + 180) % 360; |
| break; |
| case CAMERA_ID_BACK: |
| default: |
| shot_ext.shot.uctl.scalerUd.orientation = m_parameters->getFdOrientation(); |
| break; |
| } |
| |
| vraFrame->setMetaData(&shot_ext); |
| |
| if (shot_ext.fd_bypass == false) { |
| ret = m_setupEntity(vraPipeId, vraFrame, &dstBuf, &dstBuf); |
| if (ret != NO_ERROR) |
| CLOGE("ERR(%s[%d]):setupEntity fail, pipeId(%d), ret(%d)", __FUNCTION__, __LINE__, vraPipeId, ret); |
| |
| m_previewFrameFactory->setOutputFrameQToPipe(m_vraPipeDoneQ, vraPipeId); |
| m_previewFrameFactory->pushFrameToPipe(&vraFrame, vraPipeId); |
| |
| /* Wait and Pop frame from VRA output Q */ |
| CLOGV("INFO(%s[%d]):wait VRA output", __FUNCTION__, __LINE__); |
| |
| waitCount = 0; |
| do { |
| ret = m_vraPipeDoneQ->waitAndPopProcessQ(&vraDoneFrame); |
| waitCount++; |
| |
| if (m_flagThreadStop == true) { |
| if (m_vraRunningCount > 0) |
| m_vraRunningCount--; |
| return false; |
| } |
| } while (ret == TIMED_OUT && waitCount < 10); |
| |
| if (ret != NO_ERROR) |
| CLOGW("WARN(%s[%d]):VRA wait and pop error, ret(%d)", __FUNCTION__, __LINE__, ret); |
| |
| if (vraDoneFrame == NULL) { |
| CLOGE("ERR(%s[%d]):vraFrame is NULL", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| CLOGV("INFO(%s[%d]):Get frame from VRA Pipe, frameCount(%d)", __FUNCTION__, __LINE__, frameCount); |
| |
| /* Face detection callback */ |
| struct camera2_shot_ext fd_shot; |
| vraDoneFrame->getDynamicMeta(&fd_shot); |
| |
| ExynosCameraFrame *fdFrame = m_frameMgr->createFrame(m_parameters, frameCount); |
| if (fdFrame != NULL) { |
| fdFrame->storeDynamicMeta(&fd_shot); |
| m_facedetectQ->pushProcessQ(&fdFrame); |
| } |
| } |
| } |
| |
| func_exit: |
| /* Put VRA buffer */ |
| if (dstBuf.index > -1) { |
| ret = m_vraBufferMgr->putBuffer(dstBuf.index, EXYNOS_CAMERA_BUFFER_POSITION_IN_HAL); |
| if (ret != NO_ERROR) |
| CLOGW("WARN(%s[%d]):Put VRA buffer fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| } |
| |
| /* Delete frame */ |
| if (gscFrame != NULL) { |
| gscFrame->decRef(); |
| m_frameMgr->deleteFrame(gscFrame);; |
| } else if (gscDoneFrame != NULL) { |
| gscDoneFrame->decRef(); |
| m_frameMgr->deleteFrame(gscDoneFrame);; |
| } |
| |
| if (vraFrame != NULL) { |
| vraFrame->decRef(); |
| m_frameMgr->deleteFrame(vraFrame);; |
| } else if (vraDoneFrame != NULL) { |
| vraDoneFrame->decRef(); |
| m_frameMgr->deleteFrame(vraDoneFrame);; |
| } |
| |
| if (m_vraRunningCount > 0) |
| m_vraRunningCount--; |
| |
| if (m_flagThreadStop == true) { |
| CLOGI("INFO(%s[%d]):m_flagThreadStop(%d)", __FUNCTION__, __LINE__, m_flagThreadStop); |
| return false; |
| } else { |
| return true; |
| } |
| } |
| |
| status_t ExynosCamera::m_getAvailableRecordingCallbackHeapIndex(int *index) |
| { |
| if (m_recordingBufferCount <= 0 || m_recordingBufferCount > MAX_BUFFERS) { |
| CLOGE("ERR(%s[%d]):Invalid recordingBufferCount %d", |
| __FUNCTION__, __LINE__, |
| m_recordingBufferCount); |
| |
| return INVALID_OPERATION; |
| } else if (m_recordingCallbackHeap == NULL) { |
| CLOGE("ERR(%s[%d]):RecordingCallbackHeap is NULL", |
| __FUNCTION__, __LINE__); |
| |
| return INVALID_OPERATION; |
| } |
| |
| Mutex::Autolock aLock(m_recordingCallbackHeapAvailableLock); |
| for (int i = 0; i < m_recordingBufferCount; i++) { |
| if (m_recordingCallbackHeapAvailable[i] == true) { |
| CLOGV("DEBUG(%s[%d]):Found recordingCallbackHeapIndex %d", |
| __FUNCTION__, __LINE__, i); |
| |
| *index = i; |
| m_recordingCallbackHeapAvailable[i] = false; |
| return NO_ERROR; |
| } |
| } |
| |
| CLOGW("WARN(%s[%d]):There is no available recordingCallbackHeapIndex", |
| __FUNCTION__, __LINE__); |
| |
| return INVALID_OPERATION; |
| } |
| |
| status_t ExynosCamera::m_releaseRecordingCallbackHeap(struct VideoNativeHandleMetadata *addr) |
| { |
| struct VideoNativeHandleMetadata *baseAddr = NULL; |
| int recordingCallbackHeapIndex = -1; |
| |
| if (addr == NULL) { |
| CLOGE("ERR(%s[%d]):Addr is NULL", |
| __FUNCTION__, __LINE__); |
| |
| return BAD_VALUE; |
| } else if (m_recordingCallbackHeap == NULL) { |
| CLOGE("ERR(%s[%d]):RecordingCallbackHeap is NULL", |
| __FUNCTION__, __LINE__); |
| |
| return INVALID_OPERATION; |
| } |
| |
| /* Calculate the recordingCallbackHeap index base on address offest. */ |
| baseAddr = (struct VideoNativeHandleMetadata *) m_recordingCallbackHeap->data; |
| recordingCallbackHeapIndex = (int) (addr - baseAddr); |
| |
| Mutex::Autolock aLock(m_recordingCallbackHeapAvailableLock); |
| if (recordingCallbackHeapIndex < 0 || recordingCallbackHeapIndex >= m_recordingBufferCount) { |
| CLOGE("ERR(%s[%d]):Invalid index %d. base %p addr %p offset %d", |
| __FUNCTION__, __LINE__, |
| recordingCallbackHeapIndex, |
| baseAddr, |
| addr, |
| (int) (addr - baseAddr)); |
| |
| return INVALID_OPERATION; |
| } else if (m_recordingCallbackHeapAvailable[recordingCallbackHeapIndex] == true) { |
| CLOGW("WARN(%s[%d]):Already available index %d. base %p addr %p offset %d", |
| __FUNCTION__, __LINE__, |
| recordingCallbackHeapIndex, |
| baseAddr, |
| addr, |
| (int) (addr - baseAddr)); |
| } |
| |
| CLOGV("DEBUG(%s[%d]):Release recordingCallbackHeapIndex %d.", |
| __FUNCTION__, __LINE__, recordingCallbackHeapIndex); |
| |
| m_recordingCallbackHeapAvailable[recordingCallbackHeapIndex] = true; |
| |
| return NO_ERROR; |
| } |
| |
| 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_parameters->calcPreviewGSCRect(srcRect, dstRect); |
| } |
| |
| status_t ExynosCamera::m_calcHighResolutionPreviewGSCRect(ExynosRect *srcRect, ExynosRect *dstRect) |
| { |
| return m_parameters->calcHighResolutionPreviewGSCRect(srcRect, dstRect); |
| } |
| |
| status_t ExynosCamera::m_calcRecordingGSCRect(ExynosRect *srcRect, ExynosRect *dstRect) |
| { |
| return m_parameters->calcRecordingGSCRect(srcRect, dstRect); |
| } |
| |
| status_t ExynosCamera::m_calcPictureRect(ExynosRect *srcRect, ExynosRect *dstRect) |
| { |
| return m_parameters->calcPictureRect(srcRect, dstRect); |
| } |
| |
| status_t ExynosCamera::m_calcPictureRect(int originW, int originH, ExynosRect *srcRect, ExynosRect *dstRect) |
| { |
| return m_parameters->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(%zd), we remove them all", __FUNCTION__, 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 dstPipeId, 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()) { |
| newFrame = NULL; |
| 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(dstPipeId)); |
| } |
| |
| 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(%zd)", 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; |
| } |
| |
| status_t ExynosCamera::m_setPreviewCallbackBuffer(void) |
| { |
| int ret = 0; |
| int previewW = 0, previewH = 0; |
| int previewFormat = 0; |
| m_parameters->getPreviewSize(&previewW, &previewH); |
| previewFormat = m_parameters->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_parameters->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_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 [%lld msec], State:[%d]", __FUNCTION__, __LINE__, pipeId, (*threadInterval)/1000, *threadState); |
| ret = false; |
| } else { |
| CLOGV("Thread IntervalTime [%lld]", *threadInterval); |
| CLOGV("Thread Renew state [%d]", *threadState); |
| ret = NO_ERROR; |
| } |
| |
| return ret; |
| } |
| |
| #ifdef MONITOR_LOG_SYNC |
| uint32_t ExynosCamera::m_getSyncLogId(void) |
| { |
| return ++cameraSyncLogId; |
| } |
| #endif |
| |
| 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(); |
| 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_vraBufferMgr != NULL) |
| m_vraBufferMgr->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(); |
| if (m_jpegBufferMgr != NULL) |
| m_jpegBufferMgr->dump(); |
| if (m_thumbnailBufferMgr != NULL) |
| m_thumbnailBufferMgr->dump(); |
| |
| #ifdef SUPPORT_SW_VDIS |
| if (m_swVDIS_BufferMgr != NULL) |
| m_swVDIS_BufferMgr->dump(); |
| #endif /*SUPPORT_SW_VDIS*/ |
| return; |
| } |
| |
| uint32_t ExynosCamera::m_getBayerPipeId(void) |
| { |
| uint32_t pipeId = 0; |
| |
| if (m_parameters->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; |
| } |
| |
| 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_parameters->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_parameters->getPreviewFpsRange(&curMinFps, &curMaxFps); |
| |
| if (m_curMinFps != curMinFps) { |
| CLOGD("DEBUG(%s[%d]):(%d)(%d)", __FUNCTION__, __LINE__, curMinFps, curMaxFps); |
| |
| enum pipeline pipe = (m_parameters->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; |
| } |
| |
| 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_parameters->getCameraId()); |
| CLOGD("DEBUG(%s[%d]):= getDualMode : %d", __FUNCTION__, __LINE__, m_parameters->getDualMode()); |
| CLOGD("DEBUG(%s[%d]):= getScalableSensorMode : %d", __FUNCTION__, __LINE__, m_parameters->getScalableSensorMode()); |
| CLOGD("DEBUG(%s[%d]):= getRecordingHint : %d", __FUNCTION__, __LINE__, m_parameters->getRecordingHint()); |
| CLOGD("DEBUG(%s[%d]):= getEffectRecordingHint : %d", __FUNCTION__, __LINE__, m_parameters->getEffectRecordingHint()); |
| CLOGD("DEBUG(%s[%d]):= getDualRecordingHint : %d", __FUNCTION__, __LINE__, m_parameters->getDualRecordingHint()); |
| CLOGD("DEBUG(%s[%d]):= getAdaptiveCSCRecording : %d", __FUNCTION__, __LINE__, m_parameters->getAdaptiveCSCRecording()); |
| CLOGD("DEBUG(%s[%d]):= doCscRecording : %d", __FUNCTION__, __LINE__, m_parameters->doCscRecording()); |
| CLOGD("DEBUG(%s[%d]):= needGSCForCapture : %d", __FUNCTION__, __LINE__, m_parameters->needGSCForCapture(getCameraId())); |
| CLOGD("DEBUG(%s[%d]):= getShotMode : %d", __FUNCTION__, __LINE__, m_parameters->getShotMode()); |
| CLOGD("DEBUG(%s[%d]):= getTpuEnabledMode : %d", __FUNCTION__, __LINE__, m_parameters->getTpuEnabledMode()); |
| CLOGD("DEBUG(%s[%d]):= getHWVdisMode : %d", __FUNCTION__, __LINE__, m_parameters->getHWVdisMode()); |
| CLOGD("DEBUG(%s[%d]):= get3dnrMode : %d", __FUNCTION__, __LINE__, m_parameters->get3dnrMode()); |
| |
| CLOGD("DEBUG(%s[%d]):============= Internal setting ====================", __FUNCTION__, __LINE__); |
| CLOGD("DEBUG(%s[%d]):= isFlite3aaOtf : %d", __FUNCTION__, __LINE__, m_parameters->isFlite3aaOtf()); |
| CLOGD("DEBUG(%s[%d]):= is3aaIspOtf : %d", __FUNCTION__, __LINE__, m_parameters->is3aaIspOtf()); |
| CLOGD("DEBUG(%s[%d]):= isReprocessing : %d", __FUNCTION__, __LINE__, m_parameters->isReprocessing()); |
| CLOGD("DEBUG(%s[%d]):= isReprocessing3aaIspOTF : %d", __FUNCTION__, __LINE__, m_parameters->isReprocessing3aaIspOTF()); |
| CLOGD("DEBUG(%s[%d]):= getUsePureBayerReprocessing : %d", __FUNCTION__, __LINE__, m_parameters->getUsePureBayerReprocessing()); |
| |
| int reprocessingBayerMode = m_parameters->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_parameters->isSccCapture()); |
| |
| CLOGD("DEBUG(%s[%d]):============= size setting =======================", __FUNCTION__, __LINE__); |
| m_parameters->getMaxSensorSize(&w, &h); |
| CLOGD("DEBUG(%s[%d]):= getMaxSensorSize : %d x %d", __FUNCTION__, __LINE__, w, h); |
| |
| m_parameters->getHwSensorSize(&w, &h); |
| CLOGD("DEBUG(%s[%d]):= getHwSensorSize : %d x %d", __FUNCTION__, __LINE__, w, h); |
| |
| m_parameters->getBnsSize(&w, &h); |
| CLOGD("DEBUG(%s[%d]):= getBnsSize : %d x %d", __FUNCTION__, __LINE__, w, h); |
| |
| m_parameters->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_parameters->getPreviewBdsSize(&dstRect); |
| CLOGD("DEBUG(%s[%d]):= getPreviewBdsSize : (%d, %d, %d, %d)", __FUNCTION__, __LINE__, |
| dstRect.x, dstRect.y, dstRect.w, dstRect.h); |
| |
| m_parameters->getHwPreviewSize(&w, &h); |
| CLOGD("DEBUG(%s[%d]):= getHwPreviewSize : %d x %d", __FUNCTION__, __LINE__, w, h); |
| |
| m_parameters->getPreviewSize(&w, &h); |
| CLOGD("DEBUG(%s[%d]):= getPreviewSize : %d x %d", __FUNCTION__, __LINE__, w, h); |
| |
| m_parameters->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_parameters->getPictureBdsSize(&dstRect); |
| CLOGD("DEBUG(%s[%d]):= getPictureBdsSize : (%d, %d, %d, %d)", __FUNCTION__, __LINE__, |
| dstRect.x, dstRect.y, dstRect.w, dstRect.h); |
| |
| m_parameters->getHwPictureSize(&w, &h); |
| CLOGD("DEBUG(%s[%d]):= getHwPictureSize : %d x %d", __FUNCTION__, __LINE__, w, h); |
| |
| m_parameters->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_copyMetaFrameToFrame(ExynosCameraFrame *srcframe, ExynosCameraFrame *dstframe, bool useDm, bool useUdm) |
| { |
| Mutex::Autolock lock(m_metaCopyLock); |
| |
| memset(m_tempshot, 0x00, sizeof(struct camera2_shot_ext)); |
| if(useDm) { |
| srcframe->getDynamicMeta(m_tempshot); |
| dstframe->storeDynamicMeta(m_tempshot); |
| } |
| |
| if(useUdm) { |
| srcframe->getUserDynamicMeta(m_tempshot); |
| dstframe->storeUserDynamicMeta(m_tempshot); |
| } |
| |
| return NO_ERROR; |
| } |
| }; /* namespace android */ |