| /* |
| ** |
| ** Copyright 2017, 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 "ExynosCameraFrameJpegReprocessingFactory" |
| #include <log/log.h> |
| |
| #include "ExynosCameraFrameJpegReprocessingFactory.h" |
| |
| namespace android { |
| |
| ExynosCameraFrameJpegReprocessingFactory::~ExynosCameraFrameJpegReprocessingFactory() |
| { |
| status_t ret = NO_ERROR; |
| |
| if (m_shot_ext != NULL) { |
| delete m_shot_ext; |
| m_shot_ext = NULL; |
| } |
| |
| ret = destroy(); |
| if (ret != NO_ERROR) |
| CLOGE("destroy fail"); |
| } |
| |
| status_t ExynosCameraFrameJpegReprocessingFactory::create(void) |
| { |
| CLOGI(""); |
| |
| status_t ret = NO_ERROR; |
| |
| ret = ExynosCameraFrameFactoryBase::create(); |
| if (ret != NO_ERROR) { |
| CLOGE("Pipe create fail, ret(%d)", ret); |
| return ret; |
| } |
| |
| /* EOS */ |
| ret = m_pipes[INDEX(PIPE_3AA_REPROCESSING)]->setControl(V4L2_CID_IS_END_OF_STREAM, 1); |
| if (ret != NO_ERROR) { |
| CLOGE("PIPE_%s V4L2_CID_IS_END_OF_STREAM fail, ret(%d)", |
| m_pipes[INDEX(PIPE_3AA_REPROCESSING)]->getPipeName(), ret); |
| /* TODO: exception handling */ |
| return INVALID_OPERATION; |
| } |
| |
| ret = m_transitState(FRAME_FACTORY_STATE_CREATE); |
| |
| return ret; |
| } |
| |
| status_t ExynosCameraFrameJpegReprocessingFactory::initPipes(void) |
| { |
| CLOGI(""); |
| |
| status_t ret = NO_ERROR; |
| camera_pipe_info_t pipeInfo[MAX_NODE]; |
| camera_pipe_info_t nullPipeInfo; |
| |
| int pipeId = -1; |
| enum NODE_TYPE nodeType = INVALID_NODE; |
| enum NODE_TYPE leaderNodeType = OUTPUT_NODE; |
| |
| int32_t nodeNums[MAX_NODE]; |
| int32_t sensorIds[MAX_NODE]; |
| int32_t secondarySensorIds[MAX_NODE]; |
| for (int i = 0; i < MAX_NODE; i++) { |
| nodeNums[i] = -1; |
| sensorIds[i] = -1; |
| secondarySensorIds[i] = -1; |
| } |
| |
| ExynosRect tempRect; |
| ExynosRect bnsSize; |
| ExynosRect bayerCropSize; |
| int hwSensorW = 0, hwSensorH = 0; |
| int maxPreviewW = 0, maxPreviewH = 0, hwPreviewW = 0, hwPreviewH = 0; |
| int maxPictureW = 0, maxPictureH = 0, hwPictureW = 0, hwPictureH = 0; |
| int maxThumbnailW = 0, maxThumbnailH = 0; |
| int bayerFormat = m_parameters->getBayerFormat(PIPE_3AA_REPROCESSING); |
| int dsWidth = MAX_VRA_INPUT_WIDTH; |
| int dsHeight = MAX_VRA_INPUT_HEIGHT; |
| int dsFormat = m_parameters->getHwVraInputFormat(); |
| int pictureFormat = m_parameters->getHwPictureFormat(); |
| camera_pixel_size picturePixelSize = m_parameters->getHwPicturePixelSize(); |
| struct ExynosConfigInfo *config = m_configurations->getConfig(); |
| int perFramePos = 0; |
| |
| memset(&nullPipeInfo, 0, sizeof(camera_pipe_info_t)); |
| |
| #ifdef DEBUG_RAWDUMP |
| if (m_parameters->checkBayerDumpEnable()) { |
| bayerFormat = CAMERA_DUMP_BAYER_FORMAT; |
| } |
| #endif |
| |
| m_parameters->getSize(HW_INFO_HW_SENSOR_SIZE, (uint32_t *)&hwSensorW, (uint32_t *)&hwSensorH); |
| m_parameters->getSize(HW_INFO_MAX_PREVIEW_SIZE, (uint32_t *)&maxPreviewW, (uint32_t *)&maxPreviewH); |
| m_parameters->getSize(HW_INFO_HW_PREVIEW_SIZE, (uint32_t *)&hwPreviewW, (uint32_t *)&hwPreviewH); |
| m_parameters->getSize(HW_INFO_MAX_PICTURE_SIZE, (uint32_t *)&maxPictureW, (uint32_t *)&maxPictureH); |
| m_parameters->getSize(HW_INFO_HW_PICTURE_SIZE, (uint32_t *)&hwPictureW, (uint32_t *)&hwPictureH); |
| m_parameters->getSize(HW_INFO_MAX_THUMBNAIL_SIZE, (uint32_t *)&maxThumbnailW, (uint32_t *)&maxThumbnailH); |
| m_parameters->getPreviewBayerCropSize(&bnsSize, &bayerCropSize, false); |
| |
| CLOGI(" MaxPreviewSize(%dx%d), HwPreviewSize(%dx%d)", maxPreviewW, maxPreviewH, hwPreviewW, hwPreviewH); |
| CLOGI(" MaxPixtureSize(%dx%d), HwPixtureSize(%dx%d)", maxPictureW, maxPictureH, hwPictureW, hwPictureH); |
| CLOGI(" MaxThumbnailSize(%dx%d)", maxThumbnailW, maxThumbnailH); |
| CLOGI(" PreviewBayerCropSize(%dx%d)", bayerCropSize.w, bayerCropSize.h); |
| |
| CLOGI("DS Size %dx%d Format %x Buffer count %d", |
| dsWidth, dsHeight, dsFormat, config->current->bufInfo.num_vra_buffers); |
| |
| /* |
| * 3AA for Reprocessing |
| */ |
| if (m_supportPureBayerReprocessing == true) { |
| pipeId = PIPE_3AA_REPROCESSING; |
| if (m_flagPaf3aaOTF == HW_CONNECTION_MODE_OTF) { |
| /* 3PAF */ |
| uint32_t pipeId3Paf = -1; |
| #ifdef USE_PAF |
| pipeId3Paf = PIPE_3PAF_REPROCESSING; |
| #endif |
| nodeType = getNodeType(pipeId3Paf); |
| bayerFormat = m_parameters->getBayerFormat(PIPE_3AA_REPROCESSING); |
| |
| /* set v4l2 buffer size */ |
| tempRect.fullW = hwSensorW; |
| tempRect.fullH = hwSensorH; |
| tempRect.colorFormat = bayerFormat; |
| |
| /* set v4l2 video node buffer count */ |
| pipeInfo[nodeType].bufInfo.count = config->current->bufInfo.num_bayer_buffers; |
| |
| /* Set output node default info */ |
| SET_OUTPUT_DEVICE_BASIC_INFO(PERFRAME_INFO_PURE_REPROCESSING_3AA); |
| } |
| |
| /* 3AS */ |
| nodeType = getNodeType(PIPE_3AA_REPROCESSING); |
| bayerFormat = m_parameters->getBayerFormat(PIPE_3AA_REPROCESSING); |
| |
| /* set v4l2 buffer size */ |
| tempRect.fullW = hwSensorW; |
| tempRect.fullH = hwSensorH; |
| tempRect.colorFormat = bayerFormat; |
| |
| /* set v4l2 video node buffer count */ |
| pipeInfo[nodeType].bufInfo.count = config->current->bufInfo.num_bayer_buffers; |
| |
| if (m_flagPaf3aaOTF == HW_CONNECTION_MODE_OTF) { |
| SET_CAPTURE_DEVICE_BASIC_INFO(); |
| } else { |
| /* Set output node default info */ |
| SET_OUTPUT_DEVICE_BASIC_INFO(PERFRAME_INFO_PURE_REPROCESSING_3AA); |
| } |
| |
| /* 3AC */ |
| nodeType = getNodeType(PIPE_3AC_REPROCESSING); |
| perFramePos = PERFRAME_REPROCESSING_3AC_POS; |
| bayerFormat = m_parameters->getBayerFormat(PIPE_3AC_REPROCESSING); |
| |
| /* set v4l2 buffer size */ |
| tempRect.fullW = hwSensorW; |
| tempRect.fullH = hwSensorH; |
| tempRect.colorFormat = bayerFormat; |
| |
| /* set v4l2 video node buffer count */ |
| pipeInfo[nodeType].bufInfo.count = config->current->bufInfo.num_bayer_buffers; |
| |
| /* Set capture node default info */ |
| SET_CAPTURE_DEVICE_BASIC_INFO(); |
| |
| /* 3AP */ |
| nodeType = getNodeType(PIPE_3AP_REPROCESSING); |
| perFramePos = PERFRAME_REPROCESSING_3AP_POS; |
| bayerFormat = m_parameters->getBayerFormat(PIPE_3AP_REPROCESSING); |
| |
| /* set v4l2 buffer size */ |
| tempRect.fullW = hwPictureW; |
| tempRect.fullH = hwPictureH; |
| tempRect.colorFormat = bayerFormat; |
| |
| /* set v4l2 video node bytes per plane */ |
| pipeInfo[nodeType].bytesPerPlane[0] = getBayerLineSize(tempRect.fullW, bayerFormat); |
| |
| /* set v4l2 video node buffer count */ |
| pipeInfo[nodeType].bufInfo.count = config->current->bufInfo.num_reprocessing_buffers; |
| |
| /* Set capture node default info */ |
| SET_CAPTURE_DEVICE_BASIC_INFO(); |
| |
| if (m_flag3aaVraOTF == HW_CONNECTION_MODE_M2M) { |
| /* 3AF */ |
| nodeType = getNodeType(PIPE_3AF_REPROCESSING); |
| perFramePos = 0; //it is dummy info |
| // TODO: need to remove perFramePos from the SET_CAPTURE_DEVICE_BASIC_INFO |
| |
| /* set v4l2 buffer size */ |
| tempRect.fullW = MAX_VRA_INPUT_WIDTH; |
| tempRect.fullH = MAX_VRA_INPUT_HEIGHT; |
| tempRect.colorFormat = m_parameters->getHW3AFdFormat(); |
| |
| /* set v4l2 video node buffer count */ |
| pipeInfo[nodeType].bufInfo.count = config->current->bufInfo.num_vra_buffers; |
| |
| /* Set capture node default info */ |
| SET_CAPTURE_DEVICE_BASIC_INFO(); |
| } |
| |
| /* setup pipe info to 3AA pipe */ |
| if (m_flag3aaIspOTF == HW_CONNECTION_MODE_M2M) { |
| ret = m_pipes[INDEX(pipeId)]->setupPipe(pipeInfo, m_sensorIds[INDEX(pipeId)]); |
| if (ret != NO_ERROR) { |
| CLOGE("3AA setupPipe fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| return INVALID_OPERATION; |
| } |
| |
| /* clear pipeInfo for next setupPipe */ |
| for (int i = 0; i < MAX_NODE; i++) |
| pipeInfo[i] = nullPipeInfo; |
| } |
| } else { |
| /* |
| * 3A video node is opened for dirty bayer. |
| * So, we have to do setinput to 3A video node. |
| */ |
| pipeId = PIPE_3AA_REPROCESSING; |
| |
| /* setup pipe info to 3AA pipe */ |
| ret = m_pipes[INDEX(pipeId)]->setupPipe(pipeInfo, m_sensorIds[INDEX(pipeId)]); |
| if (ret != NO_ERROR) { |
| CLOGE("3AA setupPipe for dirty bayer reprocessing fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| return INVALID_OPERATION; |
| } |
| |
| /* clear pipeInfo for next setupPipe */ |
| for (int i = 0; i < MAX_NODE; i++) |
| pipeInfo[i] = nullPipeInfo; |
| } |
| |
| #ifdef USE_LLS_REPROCESSING |
| pipeId = PIPE_LLS_REPROCESSING; |
| Map_t map; |
| int maxSensorW = 0, maxSensorH = 0; |
| m_parameters->getMaxSensorSize(&maxSensorW, &maxSensorH); |
| |
| map[PLUGIN_MAX_BCROP_X] = (Map_data_t)bayerCropSize.x; |
| map[PLUGIN_MAX_BCROP_Y] = (Map_data_t)bayerCropSize.y; |
| map[PLUGIN_MAX_BCROP_W] = (Map_data_t)bayerCropSize.w; |
| map[PLUGIN_MAX_BCROP_H] = (Map_data_t)bayerCropSize.h; |
| map[PLUGIN_MAX_BCROP_FULLW] = (Map_data_t)bayerCropSize.fullW; |
| map[PLUGIN_MAX_BCROP_FULLH] = (Map_data_t)bayerCropSize.fullH; |
| map[PLUGIN_BAYER_V4L2_FORMAT] = (Map_data_t)m_parameters->getBayerFormat(PIPE_ISP_REPROCESSING); |
| |
| /* LLS */ |
| ret = m_pipes[INDEX(pipeId)]->setupPipe(&map); |
| if (ret != NO_ERROR) { |
| CLOGE("LLS setupPipe fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| return INVALID_OPERATION; |
| } |
| |
| /* LLS Capture Count setting */ |
| Data_int32_t llsCaptureCount = (Data_int32_t)map[PLUGIN_PLUGIN_MAX_SRC_BUF_CNT]; |
| m_parameters->setLLSCaptureCount(llsCaptureCount); |
| #endif |
| |
| /* |
| * ISP for Reprocessing |
| */ |
| |
| /* ISP */ |
| if (m_supportPureBayerReprocessing == false |
| || m_flag3aaIspOTF == HW_CONNECTION_MODE_M2M) { |
| pipeId = PIPE_ISP_REPROCESSING; |
| nodeType = getNodeType(PIPE_ISP_REPROCESSING); |
| bayerFormat = m_parameters->getBayerFormat(PIPE_ISP_REPROCESSING); |
| |
| /* set v4l2 buffer size */ |
| if (m_parameters->getUsePureBayerReprocessing() == true) { |
| tempRect.fullW = hwPictureW; |
| tempRect.fullH = hwPictureH; |
| } else { |
| // Dirtybayer input is bCrop size |
| tempRect.fullW = bayerCropSize.w; |
| tempRect.fullH = bayerCropSize.h; |
| } |
| tempRect.colorFormat = bayerFormat; |
| |
| /* set v4l2 video node bytes per plane */ |
| pipeInfo[nodeType].bytesPerPlane[0] = getBayerLineSize(tempRect.fullW, bayerFormat); |
| |
| /* set v4l2 video node buffer count */ |
| if(m_supportPureBayerReprocessing) { |
| pipeInfo[nodeType].bufInfo.count = config->current->bufInfo.num_reprocessing_buffers; |
| } else if (m_parameters->isSupportZSLInput()) { |
| pipeInfo[nodeType].bufInfo.count = config->current->bufInfo.num_bayer_buffers; |
| } else { |
| pipeInfo[nodeType].bufInfo.count = config->current->bufInfo.num_sensor_buffers; |
| } |
| |
| /* Set output node default info */ |
| int ispPerframeInfoIndex = m_supportPureBayerReprocessing ? PERFRAME_INFO_PURE_REPROCESSING_ISP : PERFRAME_INFO_DIRTY_REPROCESSING_ISP; |
| SET_OUTPUT_DEVICE_BASIC_INFO(ispPerframeInfoIndex); |
| } |
| |
| /* ISPC */ |
| nodeType = getNodeType(PIPE_ISPC_REPROCESSING); |
| perFramePos = PERFRAME_REPROCESSING_ISPC_POS; |
| |
| /* set v4l2 buffer size */ |
| tempRect.fullW = hwPictureW; |
| tempRect.fullH = hwPictureH; |
| tempRect.colorFormat = pictureFormat; |
| |
| /* set YUV pixel size */ |
| pipeInfo[nodeType].pixelSize = CAMERA_PIXEL_SIZE_PACKED_10BIT; |
| |
| /* set v4l2 video node buffer count */ |
| pipeInfo[nodeType].bufInfo.count = config->current->bufInfo.num_hwdis_buffers; |
| |
| /* Set capture node default info */ |
| SET_CAPTURE_DEVICE_BASIC_INFO(); |
| |
| /* ISPP */ |
| nodeType = getNodeType(PIPE_ISPP_REPROCESSING); |
| perFramePos = PERFRAME_REPROCESSING_ISPP_POS; |
| |
| /* set v4l2 buffer size */ |
| tempRect.fullW = hwPictureW; |
| tempRect.fullH = hwPictureH; |
| tempRect.colorFormat = pictureFormat; |
| |
| /* set YUV pixel size */ |
| pipeInfo[nodeType].pixelSize = picturePixelSize; |
| |
| /* set v4l2 video node buffer count */ |
| pipeInfo[nodeType].bufInfo.count = config->current->bufInfo.num_hwdis_buffers; |
| |
| /* Set capture node default info */ |
| SET_CAPTURE_DEVICE_BASIC_INFO(); |
| |
| /* setup pipe info to ISP pipe */ |
| if (m_flagIspMcscOTF == HW_CONNECTION_MODE_M2M) { |
| ret = m_pipes[INDEX(pipeId)]->setupPipe(pipeInfo, m_sensorIds[INDEX(pipeId)]); |
| if (ret != NO_ERROR) { |
| CLOGE("ISP setupPipe fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| return INVALID_OPERATION; |
| } |
| |
| /* clear pipeInfo for next setupPipe */ |
| for (int i = 0; i < MAX_NODE; i++) |
| pipeInfo[i] = nullPipeInfo; |
| } |
| |
| /* |
| * MCSC for Reprocessing |
| */ |
| |
| /* MCSC */ |
| if (m_flagIspMcscOTF == HW_CONNECTION_MODE_M2M) { |
| pipeId = PIPE_MCSC_REPROCESSING; |
| nodeType = getNodeType(PIPE_MCSC_REPROCESSING); |
| |
| /* set v4l2 buffer size */ |
| tempRect.fullW = hwPictureW; |
| tempRect.fullH = hwPictureH; |
| tempRect.colorFormat = pictureFormat; |
| |
| /* set YUV pixel size */ |
| pipeInfo[nodeType].pixelSize = picturePixelSize; |
| |
| /* set v4l2 video node buffer count */ |
| pipeInfo[nodeType].bufInfo.count = config->current->bufInfo.num_hwdis_buffers; |
| |
| /* Set output node default info */ |
| int mcscPerframeInfoIndex = m_supportPureBayerReprocessing ? PERFRAME_INFO_PURE_REPROCESSING_MCSC : PERFRAME_INFO_DIRTY_REPROCESSING_MCSC; |
| SET_OUTPUT_DEVICE_BASIC_INFO(mcscPerframeInfoIndex); |
| } |
| |
| /* Jpeg Main */ |
| nodeType = getNodeType(PIPE_MCSC_JPEG_REPROCESSING); |
| perFramePos = PERFRAME_REPROCESSING_MCSC_JPEG_POS; |
| |
| /* set v4l2 buffer size */ |
| tempRect.fullW = hwPictureW; |
| tempRect.fullH = hwPictureH; |
| tempRect.colorFormat = pictureFormat; |
| |
| /* set YUV pixel size */ |
| pipeInfo[nodeType].pixelSize = picturePixelSize; |
| |
| /* set v4l2 video node buffer count */ |
| pipeInfo[nodeType].bufInfo.count = config->current->bufInfo.num_reprocessing_buffers; |
| |
| /* Set capture node default info */ |
| SET_CAPTURE_DEVICE_BASIC_INFO(); |
| |
| /* Jpeg Thumbnail */ |
| nodeType = getNodeType(PIPE_MCSC_THUMB_REPROCESSING); |
| perFramePos = PERFRAME_REPROCESSING_MCSC_THUMB_POS; |
| |
| /* set v4l2 buffer size */ |
| tempRect.fullW = maxThumbnailW; |
| tempRect.fullH = maxThumbnailH; |
| tempRect.colorFormat = pictureFormat; |
| |
| /* set YUV pixel size */ |
| pipeInfo[nodeType].pixelSize = picturePixelSize; |
| |
| /* set v4l2 video node buffer count */ |
| pipeInfo[nodeType].bufInfo.count = config->current->bufInfo.num_reprocessing_buffers; |
| |
| /* Set capture node default info */ |
| SET_CAPTURE_DEVICE_BASIC_INFO(); |
| |
| if (m_flagHWFCEnabled == true) { |
| #ifdef SUPPORT_HWFC_SERIALIZATION |
| /* Do serialized Q/DQ operation to guarantee the H/W flow control sequence limitation */ |
| m_pipes[INDEX(pipeId)]->needSerialization(true); |
| #endif |
| |
| /* JPEG Src */ |
| nodeType = getNodeType(PIPE_HWFC_JPEG_SRC_REPROCESSING); |
| |
| /* set v4l2 buffer size */ |
| tempRect.fullW = hwPictureW; |
| tempRect.fullH = hwPictureH; |
| tempRect.colorFormat = pictureFormat; |
| |
| /* set YUV pixel size */ |
| pipeInfo[nodeType].pixelSize = picturePixelSize; |
| |
| /* set v4l2 video node buffer count */ |
| pipeInfo[nodeType].bufInfo.count = config->current->bufInfo.num_reprocessing_buffers; |
| |
| /* Set capture node default info */ |
| pipeInfo[nodeType].rectInfo = tempRect; |
| pipeInfo[nodeType].bufInfo.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
| pipeInfo[nodeType].bufInfo.memory = V4L2_CAMERA_MEMORY_TYPE; |
| |
| /* Thumbnail Src */ |
| nodeType = getNodeType(PIPE_HWFC_THUMB_SRC_REPROCESSING); |
| |
| /* set v4l2 buffer size */ |
| tempRect.fullW = maxThumbnailW; |
| tempRect.fullH = maxThumbnailH; |
| tempRect.colorFormat = pictureFormat; |
| |
| /* set YUV pixel size */ |
| pipeInfo[nodeType].pixelSize = picturePixelSize; |
| |
| /* set v4l2 video node buffer count */ |
| pipeInfo[nodeType].bufInfo.count = config->current->bufInfo.num_reprocessing_buffers; |
| |
| /* Set capture node default info */ |
| pipeInfo[nodeType].rectInfo = tempRect; |
| pipeInfo[nodeType].bufInfo.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
| pipeInfo[nodeType].bufInfo.memory = V4L2_CAMERA_MEMORY_TYPE; |
| |
| /* JPEG Dst */ |
| nodeType = getNodeType(PIPE_HWFC_JPEG_DST_REPROCESSING); |
| |
| /* set v4l2 buffer size */ |
| tempRect.fullW = hwPictureW; |
| tempRect.fullH = hwPictureH; |
| tempRect.colorFormat = pictureFormat; |
| |
| /* set YUV pixel size */ |
| pipeInfo[nodeType].pixelSize = picturePixelSize; |
| |
| /* set v4l2 video node buffer count */ |
| pipeInfo[nodeType].bufInfo.count = config->current->bufInfo.num_picture_buffers; |
| |
| /* Set capture node default info */ |
| pipeInfo[nodeType].rectInfo = tempRect; |
| pipeInfo[nodeType].bufInfo.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
| pipeInfo[nodeType].bufInfo.memory = V4L2_CAMERA_MEMORY_TYPE; |
| |
| /* Thumbnail Dst */ |
| nodeType = getNodeType(PIPE_HWFC_THUMB_DST_REPROCESSING); |
| |
| /* set v4l2 buffer size */ |
| tempRect.fullW = maxThumbnailW; |
| tempRect.fullH = maxThumbnailH; |
| tempRect.colorFormat = pictureFormat; |
| |
| /* set YUV pixel size */ |
| pipeInfo[nodeType].pixelSize = picturePixelSize; |
| |
| /* set v4l2 video node buffer count */ |
| pipeInfo[nodeType].bufInfo.count = config->current->bufInfo.num_reprocessing_buffers; |
| |
| /* Set capture node default info */ |
| pipeInfo[nodeType].rectInfo = tempRect; |
| pipeInfo[nodeType].bufInfo.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
| pipeInfo[nodeType].bufInfo.memory = V4L2_CAMERA_MEMORY_TYPE; |
| } |
| |
| if (m_flagMcscVraOTF == HW_CONNECTION_MODE_M2M) { |
| /* MCSC5 */ |
| nodeType = getNodeType(PIPE_MCSC5_REPROCESSING); |
| perFramePos = PERFRAME_REPROCESSING_MCSC5_POS; |
| |
| /* set v4l2 buffer size */ |
| tempRect.fullW = dsWidth; |
| tempRect.fullH = dsHeight; |
| tempRect.colorFormat = dsFormat; |
| |
| /* set v4l2 video node buffer count */ |
| pipeInfo[nodeType].bufInfo.count = config->current->bufInfo.num_vra_buffers; |
| |
| /* Set capture node default info */ |
| SET_CAPTURE_DEVICE_BASIC_INFO(); |
| |
| ret = m_pipes[INDEX(pipeId)]->setupPipe(pipeInfo, m_sensorIds[INDEX(pipeId)]); |
| if (ret != NO_ERROR) { |
| CLOGE("MCSC setupPipe fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| return INVALID_OPERATION; |
| } |
| |
| /* clear pipeInfo for next setupPipe */ |
| for (int i = 0; i < MAX_NODE; i++) |
| pipeInfo[i] = nullPipeInfo; |
| } |
| |
| /* VRA */ |
| if (m_flagMcscVraOTF == HW_CONNECTION_MODE_M2M) { |
| pipeId = PIPE_VRA_REPROCESSING; |
| nodeType = getNodeType(PIPE_VRA_REPROCESSING); |
| |
| /* set v4l2 buffer size */ |
| tempRect.fullW = dsWidth; |
| tempRect.fullH = dsHeight; |
| tempRect.colorFormat = dsFormat; |
| |
| /* set v4l2 video node buffer count */ |
| pipeInfo[nodeType].bufInfo.count = config->current->bufInfo.num_vra_buffers; |
| |
| /* Set output node default info */ |
| SET_OUTPUT_DEVICE_BASIC_INFO(PERFRAME_INFO_VRA); |
| } |
| |
| ret = m_pipes[INDEX(pipeId)]->setupPipe(pipeInfo, m_sensorIds[INDEX(pipeId)]); |
| if (ret != NO_ERROR) { |
| CLOGE("ISP setupPipe fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| return INVALID_OPERATION; |
| } |
| |
| /* VRA */ |
| if ((m_flag3aaVraOTF == HW_CONNECTION_MODE_M2M) && |
| (m_flagMcscVraOTF != HW_CONNECTION_MODE_M2M)) { |
| /* clear pipeInfo for next setupPipe */ |
| for (int i = 0; i < MAX_NODE; i++) |
| pipeInfo[i] = nullPipeInfo; |
| |
| pipeId = PIPE_VRA_REPROCESSING; |
| nodeType = getNodeType(PIPE_VRA_REPROCESSING); |
| |
| /* set v4l2 buffer size */ |
| tempRect.fullW = dsWidth; |
| tempRect.fullH = dsWidth; |
| tempRect.colorFormat = dsFormat; |
| |
| /* set v4l2 video node buffer count */ |
| pipeInfo[nodeType].bufInfo.count = config->current->bufInfo.num_vra_buffers; |
| |
| /* Set output node default info */ |
| SET_OUTPUT_DEVICE_BASIC_INFO(PERFRAME_INFO_VRA); |
| |
| ret = m_pipes[pipeId]->setupPipe(pipeInfo, m_sensorIds[pipeId]); |
| if (ret != NO_ERROR) { |
| CLOGE("VRA setupPipe fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| return INVALID_OPERATION; |
| } |
| } |
| m_frameCount = 0; |
| |
| ret = m_transitState(FRAME_FACTORY_STATE_INIT); |
| |
| return ret; |
| } |
| |
| status_t ExynosCameraFrameJpegReprocessingFactory::preparePipes(void) |
| { |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCameraFrameJpegReprocessingFactory::startPipes(void) |
| { |
| status_t ret = NO_ERROR; |
| CLOGI(""); |
| |
| /* VRA Reprocessing */ |
| if ((m_flagMcscVraOTF == HW_CONNECTION_MODE_M2M) || |
| (m_flag3aaVraOTF == HW_CONNECTION_MODE_M2M)) { |
| ret = m_pipes[INDEX(PIPE_VRA_REPROCESSING)]->start(); |
| if (ret != NO_ERROR) { |
| CLOGE("VRA start fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| return INVALID_OPERATION; |
| } |
| } |
| |
| /* MCSC Reprocessing */ |
| if (m_flagIspMcscOTF == HW_CONNECTION_MODE_M2M) { |
| ret = m_pipes[INDEX(PIPE_MCSC_REPROCESSING)]->start(); |
| if (ret != NO_ERROR) { |
| CLOGE("MCSC start fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| return INVALID_OPERATION; |
| } |
| } |
| |
| /* ISP Reprocessing */ |
| if (m_flag3aaIspOTF == HW_CONNECTION_MODE_M2M) { |
| ret = m_pipes[INDEX(PIPE_ISP_REPROCESSING)]->start(); |
| if (ret != NO_ERROR) { |
| CLOGE("ISP start fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| return INVALID_OPERATION; |
| } |
| } |
| |
| #ifdef USE_LLS_REPROCESSING |
| ret = m_pipes[INDEX(PIPE_LLS_REPROCESSING)]->start(); |
| if (ret != NO_ERROR) { |
| CLOGE("LLS_REPROCESSING start fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| return INVALID_OPERATION; |
| } |
| #endif |
| |
| /* 3AA Reprocessing */ |
| if (m_supportPureBayerReprocessing == true) { |
| ret = m_pipes[INDEX(PIPE_3AA_REPROCESSING)]->start(); |
| if (ret != NO_ERROR) { |
| CLOGE("ISP start fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| return INVALID_OPERATION; |
| } |
| } |
| |
| ret = m_transitState(FRAME_FACTORY_STATE_RUN); |
| if (ret != NO_ERROR) { |
| CLOGE("Failed to transitState. ret %d", ret); |
| return ret; |
| } |
| |
| CLOGI("Starting Reprocessing [SCC>ISP] Success!"); |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCameraFrameJpegReprocessingFactory::stopPipes(void) |
| { |
| status_t ret = NO_ERROR; |
| status_t funcRet = NO_ERROR; |
| CLOGI(""); |
| |
| /* 3AA Reprocessing Thread stop */ |
| if (m_supportPureBayerReprocessing == true) { |
| ret = m_pipes[INDEX(PIPE_3AA_REPROCESSING)]->stopThread(); |
| if (ret != NO_ERROR) { |
| CLOGE("ISP stopThread fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| funcRet |= ret; |
| } |
| } |
| |
| #ifdef USE_LLS_REPROCESSING |
| if (m_pipes[INDEX(PIPE_LLS_REPROCESSING)] != NULL && |
| m_pipes[INDEX(PIPE_LLS_REPROCESSING)]->isThreadRunning() == true) { |
| ret = stopThread(INDEX(PIPE_LLS_REPROCESSING)); |
| if (ret < 0) { |
| CLOGE("PIPE_LLS_REPROCESSING stopThread fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| funcRet |= ret; |
| } |
| } |
| #endif |
| |
| /* ISP Reprocessing Thread stop */ |
| if (m_flag3aaIspOTF == HW_CONNECTION_MODE_M2M) { |
| ret = m_pipes[INDEX(PIPE_ISP_REPROCESSING)]->stopThread(); |
| if (ret != NO_ERROR) { |
| CLOGE("ISP stopThread fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| funcRet |= ret; |
| } |
| } |
| |
| /* MCSC Reprocessing Thread stop */ |
| if (m_flagIspMcscOTF == HW_CONNECTION_MODE_M2M) { |
| ret = m_pipes[INDEX(PIPE_MCSC_REPROCESSING)]->stopThread(); |
| if (ret != NO_ERROR) { |
| CLOGE("MCSC stopThread fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| funcRet |= ret; |
| } |
| } |
| |
| if (m_pipes[INDEX(PIPE_VRA_REPROCESSING)]->isThreadRunning() == true) { |
| ret = m_pipes[INDEX(PIPE_VRA_REPROCESSING)]->stopThread(); |
| if (ret != NO_ERROR) { |
| CLOGE("VRA stopThread fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| funcRet |= ret; |
| } |
| } |
| |
| /* 3AA Reprocessing stop */ |
| if (m_supportPureBayerReprocessing == true) { |
| ret = m_pipes[INDEX(PIPE_3AA_REPROCESSING)]->stop(); |
| if (ret != NO_ERROR) { |
| CLOGE("ISP stop fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| funcRet |= ret; |
| } |
| } |
| |
| #ifdef USE_LLS_REPROCESSING |
| if (m_pipes[INDEX(PIPE_LLS_REPROCESSING)] != NULL && |
| m_pipes[INDEX(PIPE_LLS_REPROCESSING)]->isThreadRunning() == true) { |
| m_pipes[INDEX(PIPE_LLS_REPROCESSING)]->stop(); |
| if (ret < 0) { |
| CLOGE("m_pipes[INDEX(PIPE_LLS_REPROCESSING)]->stop() fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| funcRet |= ret; |
| } |
| } |
| #endif |
| |
| /* ISP Reprocessing stop */ |
| if (m_flag3aaIspOTF == HW_CONNECTION_MODE_M2M) { |
| ret = m_pipes[INDEX(PIPE_ISP_REPROCESSING)]->stop(); |
| if (ret != NO_ERROR) { |
| CLOGE("ISP stop fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| funcRet |= ret; |
| } |
| } |
| |
| /* MCSC Reprocessing stop */ |
| if (m_flagIspMcscOTF == HW_CONNECTION_MODE_M2M) { |
| ret = m_pipes[INDEX(PIPE_MCSC_REPROCESSING)]->stop(); |
| if (ret != NO_ERROR) { |
| CLOGE("MCSC stop fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| funcRet |= ret; |
| } |
| } |
| |
| if (m_pipes[INDEX(PIPE_VRA_REPROCESSING)]->flagStart() == true) { |
| ret = m_pipes[INDEX(PIPE_VRA_REPROCESSING)]->stop(); |
| if (ret != NO_ERROR) { |
| CLOGE("VRA stop fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| funcRet |= ret; |
| } |
| } |
| |
| if (m_flagHWFCEnabled == false || (m_flagHWFCEnabled && m_parameters->isHWFCOnDemand())) { |
| /* JPEG Reprocessing stop */ |
| ret = m_pipes[INDEX(PIPE_JPEG_REPROCESSING)]->stop(); |
| if (ret != NO_ERROR) { |
| CLOGE("JPEG stop fail, ret(%d)", ret); |
| /* TODO: exception handling */ |
| funcRet |= ret; |
| } |
| } |
| |
| /* GSC2 Reprocessing stop */ |
| ret = stopThreadAndWait(PIPE_GSC_REPROCESSING2); |
| if (ret != NO_ERROR) { |
| CLOGE("PIPE_GSC_REPROCESSING2 stopThreadAndWait fail, ret(%d)", ret); |
| } |
| |
| /* GSC3 Reprocessing stop */ |
| ret = stopThreadAndWait(PIPE_GSC_REPROCESSING3); |
| if (ret != NO_ERROR) { |
| CLOGE("PIPE_GSC_REPROCESSING3 stopThreadAndWait fail, ret(%d)", ret); |
| } |
| |
| ret = m_transitState(FRAME_FACTORY_STATE_CREATE); |
| if (ret != NO_ERROR) { |
| CLOGE("Failed to transitState. ret %d", |
| ret); |
| funcRet |= ret; |
| } |
| |
| CLOGI("Stopping Reprocessing [3AA>MCSC] Success!"); |
| |
| return funcRet; |
| } |
| |
| status_t ExynosCameraFrameJpegReprocessingFactory::startInitialThreads(void) |
| { |
| CLOGI("start pre-ordered initial pipe thread"); |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCameraFrameJpegReprocessingFactory::setStopFlag(void) |
| { |
| CLOGI(""); |
| |
| status_t ret = NO_ERROR; |
| |
| if (m_pipes[INDEX(PIPE_3AA_REPROCESSING)]->flagStart() == true) |
| ret = m_pipes[INDEX(PIPE_3AA_REPROCESSING)]->setStopFlag(); |
| |
| #ifdef USE_LLS_REPROCESSING |
| if (m_pipes[INDEX(PIPE_LLS_REPROCESSING)] != NULL && |
| m_pipes[INDEX(PIPE_LLS_REPROCESSING)]->flagStart() == true) { |
| ret = m_pipes[INDEX(PIPE_LLS_REPROCESSING)]->setStopFlag(); |
| } |
| #endif |
| |
| if (m_pipes[INDEX(PIPE_ISP_REPROCESSING)]->flagStart() == true) |
| ret = m_pipes[INDEX(PIPE_ISP_REPROCESSING)]->setStopFlag(); |
| |
| if (m_pipes[INDEX(PIPE_MCSC_REPROCESSING)]->flagStart() == true) |
| ret = m_pipes[INDEX(PIPE_MCSC_REPROCESSING)]->setStopFlag(); |
| |
| if (m_pipes[INDEX(PIPE_VRA_REPROCESSING)]->flagStart() == true) |
| ret = m_pipes[INDEX(PIPE_VRA_REPROCESSING)]->setStopFlag(); |
| |
| return NO_ERROR; |
| } |
| |
| status_t ExynosCameraFrameJpegReprocessingFactory::m_fillNodeGroupInfo(ExynosCameraFrameSP_sptr_t frame) |
| { |
| camera2_node_group node_group_info_3aa; |
| camera2_node_group node_group_info_isp; |
| camera2_node_group node_group_info_mcsc; |
| camera2_node_group node_group_info_vra; |
| camera2_node_group *node_group_info_temp = NULL; |
| |
| float zoomRatio = m_configurations->getZoomRatio(); |
| int pipeId = -1; |
| int nodePipeId = -1; |
| uint32_t perframePosition = 0; |
| |
| memset(&node_group_info_3aa, 0x0, sizeof(camera2_node_group)); |
| memset(&node_group_info_isp, 0x0, sizeof(camera2_node_group)); |
| memset(&node_group_info_mcsc, 0x0, sizeof(camera2_node_group)); |
| memset(&node_group_info_vra, 0x0, sizeof(camera2_node_group)); |
| |
| /* 3AA for Reprocessing */ |
| if (m_supportPureBayerReprocessing == true) { |
| pipeId = INDEX(PIPE_3AA_REPROCESSING); |
| node_group_info_temp = &node_group_info_3aa; |
| node_group_info_temp->leader.request = 1; |
| node_group_info_temp->leader.pixelformat = m_parameters->getBayerFormat(pipeId); |
| |
| nodePipeId = PIPE_3AC_REPROCESSING; |
| if (m_request[INDEX(nodePipeId)] == true) { |
| node_group_info_temp->capture[perframePosition].request = m_request[INDEX(nodePipeId)]; |
| node_group_info_temp->capture[perframePosition].vid = m_deviceInfo[pipeId].nodeNum[getNodeType(nodePipeId)] - FIMC_IS_VIDEO_BAS_NUM; |
| node_group_info_temp->capture[perframePosition].pixelformat = m_parameters->getBayerFormat(nodePipeId); |
| perframePosition++; |
| } |
| |
| nodePipeId = PIPE_3AP_REPROCESSING; |
| node_group_info_temp->capture[perframePosition].request = m_request[INDEX(nodePipeId)]; |
| node_group_info_temp->capture[perframePosition].vid = m_deviceInfo[pipeId].nodeNum[getNodeType(nodePipeId)] - FIMC_IS_VIDEO_BAS_NUM; |
| node_group_info_temp->capture[perframePosition].pixelformat = m_parameters->getBayerFormat(nodePipeId); |
| perframePosition++; |
| |
| /* VRA */ |
| if (m_flag3aaVraOTF == HW_CONNECTION_MODE_M2M) { |
| nodePipeId = PIPE_3AF_REPROCESSING; |
| node_group_info_temp->capture[perframePosition].request = m_request[INDEX(nodePipeId)]; |
| node_group_info_temp->capture[perframePosition].vid = m_deviceInfo[pipeId].nodeNum[getNodeType(nodePipeId)] - FIMC_IS_VIDEO_BAS_NUM; |
| node_group_info_temp->capture[perframePosition].pixelformat = m_parameters->getHwVraInputFormat(); |
| perframePosition++; |
| } |
| } |
| |
| /* ISP for Reprocessing */ |
| if (m_supportPureBayerReprocessing == false |
| || m_flag3aaIspOTF == HW_CONNECTION_MODE_M2M) { |
| pipeId = INDEX(PIPE_ISP_REPROCESSING); |
| perframePosition = 0; |
| node_group_info_temp = &node_group_info_isp; |
| node_group_info_temp->leader.request = 1; |
| node_group_info_temp->leader.pixelformat = m_parameters->getBayerFormat(pipeId); |
| } |
| |
| nodePipeId = PIPE_ISPC_REPROCESSING; |
| if (m_request[INDEX(nodePipeId)] == true && node_group_info_temp != NULL) { |
| nodePipeId = PIPE_ISPC_REPROCESSING; |
| node_group_info_temp->capture[perframePosition].request = m_request[INDEX(nodePipeId)]; |
| node_group_info_temp->capture[perframePosition].vid = m_deviceInfo[pipeId].nodeNum[getNodeType(nodePipeId)] - FIMC_IS_VIDEO_BAS_NUM; |
| node_group_info_temp->capture[perframePosition].pixelformat = m_parameters->getHwPictureFormat(); |
| perframePosition++; |
| } |
| |
| nodePipeId = PIPE_ISPP_REPROCESSING; |
| if (m_request[INDEX(nodePipeId)] == true && node_group_info_temp != NULL) { |
| node_group_info_temp->capture[perframePosition].request = m_request[INDEX(nodePipeId)]; |
| node_group_info_temp->capture[perframePosition].vid = m_deviceInfo[pipeId].nodeNum[getNodeType(nodePipeId)] - FIMC_IS_VIDEO_BAS_NUM; |
| node_group_info_temp->capture[perframePosition].pixelformat = m_parameters->getHwPictureFormat(); |
| perframePosition++; |
| } |
| |
| /* MCSC for Reprocessing */ |
| if (m_flagIspMcscOTF == HW_CONNECTION_MODE_M2M) { |
| pipeId = INDEX(PIPE_MCSC_REPROCESSING); |
| perframePosition = 0; |
| node_group_info_temp = &node_group_info_mcsc; |
| node_group_info_temp->leader.request = 1; |
| node_group_info_temp->leader.pixelformat = m_parameters->getHwPictureFormat(); |
| } |
| |
| if (node_group_info_temp != NULL) { |
| nodePipeId = PIPE_MCSC_JPEG_REPROCESSING; |
| node_group_info_temp->capture[perframePosition].request = m_request[INDEX(nodePipeId)]; |
| node_group_info_temp->capture[perframePosition].vid = m_deviceInfo[pipeId].nodeNum[getNodeType(nodePipeId)] - FIMC_IS_VIDEO_BAS_NUM; |
| node_group_info_temp->capture[perframePosition].pixelformat = m_parameters->getHwPictureFormat(); |
| perframePosition++; |
| |
| nodePipeId = PIPE_MCSC_THUMB_REPROCESSING; |
| node_group_info_temp->capture[perframePosition].request = m_request[INDEX(nodePipeId)]; |
| node_group_info_temp->capture[perframePosition].vid = m_deviceInfo[pipeId].nodeNum[getNodeType(nodePipeId)] - FIMC_IS_VIDEO_BAS_NUM; |
| node_group_info_temp->capture[perframePosition].pixelformat = m_parameters->getHwPictureFormat(); |
| perframePosition++; |
| |
| if (m_flagMcscVraOTF == HW_CONNECTION_MODE_M2M) { |
| nodePipeId = PIPE_MCSC5_REPROCESSING; |
| node_group_info_temp->capture[perframePosition].request = m_request[INDEX(nodePipeId)]; |
| node_group_info_temp->capture[perframePosition].vid = m_deviceInfo[pipeId].nodeNum[getNodeType(nodePipeId)] - FIMC_IS_VIDEO_BAS_NUM; |
| node_group_info_temp->capture[perframePosition].pixelformat = m_parameters->getHwVraInputFormat(); |
| perframePosition++; |
| } |
| } |
| |
| /* VRA */ |
| if ((m_flag3aaVraOTF == HW_CONNECTION_MODE_M2M) || |
| (m_flagMcscVraOTF == HW_CONNECTION_MODE_M2M)) { |
| pipeId = INDEX(PIPE_VRA_REPROCESSING); |
| perframePosition = 0; |
| node_group_info_temp = &node_group_info_vra; |
| node_group_info_temp->leader.request = 1; |
| node_group_info_temp->leader.pixelformat = m_parameters->getHwVraInputFormat(); |
| } |
| |
| frame->setZoomRatio(zoomRatio); |
| |
| updateNodeGroupInfo( |
| PIPE_3AA_REPROCESSING, |
| frame, |
| &node_group_info_3aa); |
| frame->storeNodeGroupInfo(&node_group_info_3aa, PERFRAME_INFO_PURE_REPROCESSING_3AA); |
| |
| if (m_supportPureBayerReprocessing == false |
| || m_flag3aaIspOTF == HW_CONNECTION_MODE_M2M) { |
| updateNodeGroupInfo( |
| PIPE_ISP_REPROCESSING, |
| frame, |
| &node_group_info_isp); |
| if (m_supportPureBayerReprocessing == true) |
| frame->storeNodeGroupInfo(&node_group_info_isp, PERFRAME_INFO_PURE_REPROCESSING_ISP); |
| else |
| frame->storeNodeGroupInfo(&node_group_info_isp, PERFRAME_INFO_DIRTY_REPROCESSING_ISP); |
| } |
| |
| if ((m_flag3aaVraOTF == HW_CONNECTION_MODE_M2M) || |
| (m_flagMcscVraOTF == HW_CONNECTION_MODE_M2M)) { |
| updateNodeGroupInfo( |
| PIPE_VRA_REPROCESSING, |
| frame, |
| &node_group_info_vra); |
| if (m_supportPureBayerReprocessing == true) |
| frame->storeNodeGroupInfo(&node_group_info_vra, PERFRAME_INFO_PURE_REPROCESSING_VRA); |
| else |
| frame->storeNodeGroupInfo(&node_group_info_vra, PERFRAME_INFO_DIRTY_REPROCESSING_VRA); |
| } |
| |
| return NO_ERROR; |
| } |
| |
| void ExynosCameraFrameJpegReprocessingFactory::m_init(void) |
| { |
| m_flagReprocessing = true; |
| m_flagHWFCEnabled = m_parameters->isUseHWFC(); |
| |
| m_shot_ext = new struct camera2_shot_ext; |
| } |
| |
| }; /* namespace android */ |