blob: e97c08caf0bee3c57af9f8cc5dae0d74129903c3 [file] [log] [blame]
/*
**
** 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 */