blob: d09075eb151efa43cf5fc169051fa78e744c9321 [file] [log] [blame]
/*
**
** Copyright 2014, 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 "ExynosCameraFrameFactoryVision"
#include <cutils/log.h>
#include "ExynosCameraFrameFactoryVision.h"
namespace android {
ExynosCameraFrameFactoryVision::~ExynosCameraFrameFactoryVision()
{
int ret = 0;
ret = destroy();
if (ret < 0)
CLOGE("ERR(%s[%d]):destroy fail", __FUNCTION__, __LINE__);
}
status_t ExynosCameraFrameFactoryVision::create(__unused bool active)
{
CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__);
m_setupConfig();
int ret = 0;
int32_t nodeNums[MAX_NODE] = {-1, -1, -1};
m_pipes[INDEX(PIPE_FLITE)] = (ExynosCameraPipe*)new ExynosCameraPipeFlite(m_cameraId, m_parameters, false, m_nodeNums[INDEX(PIPE_FLITE)]);
m_pipes[INDEX(PIPE_FLITE)]->setPipeId(PIPE_FLITE);
m_pipes[INDEX(PIPE_FLITE)]->setPipeName("PIPE_FLITE");
/* flite pipe initialize */
ret = m_pipes[INDEX(PIPE_FLITE)]->create();
if (ret < 0) {
CLOGE("ERR(%s[%d]):FLITE create fail, ret(%d)", __FUNCTION__, __LINE__, ret);
/* TODO: exception handling */
return INVALID_OPERATION;
}
m_setCreate(true);
CLOGD("DEBUG(%s):Pipe(%d) created", __FUNCTION__, INDEX(PIPE_FLITE));
return NO_ERROR;
}
status_t ExynosCameraFrameFactoryVision::destroy(void)
{
CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__);
status_t ret = NO_ERROR;
for (int i = 0; i < MAX_NUM_PIPES; i++) {
if (m_pipes[i] != NULL) {
ret = m_pipes[i]->destroy();
if (ret != NO_ERROR) {
CLOGE("ERR(%s[%d]):m_pipes[%d]->destroy() fail", __FUNCTION__, __LINE__, i);
return ret;
}
SAFE_DELETE(m_pipes[i]);
CLOGD("DEBUG(%s):Pipe(%d) destroyed", __FUNCTION__, i);
}
}
m_setCreate(false);
return NO_ERROR;
}
status_t ExynosCameraFrameFactoryVision::m_fillNodeGroupInfo(__unused ExynosCameraFrame *frame)
{
/* Do nothing */
return NO_ERROR;
}
ExynosCameraFrame *ExynosCameraFrameFactoryVision::createNewFrame(void)
{
int ret = 0;
ExynosCameraFrameEntity *newEntity[MAX_NUM_PIPES];
ExynosCameraFrame *frame = m_frameMgr->createFrame(m_parameters, m_frameCount);
int requestEntityCount = 0;
CLOGV("INFO(%s[%d])", __FUNCTION__, __LINE__);
ret = m_initFrameMetadata(frame);
if (ret < 0)
CLOGE("(%s[%d]): frame(%d) metadata initialize fail", __FUNCTION__, __LINE__, m_frameCount);
/* set flite pipe to linkageList */
newEntity[INDEX(PIPE_FLITE)] = new ExynosCameraFrameEntity(PIPE_FLITE, ENTITY_TYPE_OUTPUT_ONLY, ENTITY_BUFFER_FIXED);
frame->addSiblingEntity(NULL, newEntity[INDEX(PIPE_FLITE)]);
requestEntityCount++;
ret = m_initPipelines(frame);
if (ret < 0) {
CLOGE("ERR(%s):m_initPipelines fail, ret(%d)", __FUNCTION__, ret);
}
m_fillNodeGroupInfo(frame);
/* TODO: make it dynamic */
frame->setNumRequestPipe(requestEntityCount);
m_frameCount++;
return frame;
}
status_t ExynosCameraFrameFactoryVision::initPipes(void)
{
CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__);
int ret = 0;
camera_pipe_info_t pipeInfo[3];
int32_t nodeNums[MAX_NODE] = {-1, -1, -1};
int32_t sensorIds[MAX_NODE] = {-1, -1, -1};
ExynosRect tempRect;
int maxSensorW = 0, maxSensorH = 0, hwSensorW = 0, hwSensorH = 0;
int maxPreviewW = 0, maxPreviewH = 0, hwPreviewW = 0, hwPreviewH = 0;
int maxPictureW = 0, maxPictureH = 0, hwPictureW = 0, hwPictureH = 0;
int bayerFormat = V4L2_PIX_FMT_SBGGR12;
int previewFormat = m_parameters->getHwPreviewFormat();
int pictureFormat = m_parameters->getHwPictureFormat();
m_parameters->getMaxSensorSize(&maxSensorW, &maxSensorH);
m_parameters->getHwSensorSize(&hwSensorW, &hwSensorH);
m_parameters->getMaxPreviewSize(&maxPreviewW, &maxPreviewH);
m_parameters->getHwPreviewSize(&hwPreviewW, &hwPreviewH);
m_parameters->getMaxPictureSize(&maxPictureW, &maxPictureH);
m_parameters->getHwPictureSize(&hwPictureW, &hwPictureH);
CLOGI("INFO(%s[%d]): MaxSensorSize(%dx%d), HwSensorSize(%dx%d)", __FUNCTION__, __LINE__, maxSensorW, maxSensorH, hwSensorW, hwSensorH);
CLOGI("INFO(%s[%d]): MaxPreviewSize(%dx%d), HwPreviewSize(%dx%d)", __FUNCTION__, __LINE__, maxPreviewW, maxPreviewH, hwPreviewW, hwPreviewH);
CLOGI("INFO(%s[%d]): MaxPixtureSize(%dx%d), HwPixtureSize(%dx%d)", __FUNCTION__, __LINE__, maxPictureW, maxPictureH, hwPictureW, hwPictureH);
memset(pipeInfo, 0, (sizeof(camera_pipe_info_t) * 3));
/* FLITE pipe */
#ifdef SAMSUNG_TN_FEATURE
if (m_cameraId == CAMERA_ID_SECURE) {
tempRect.fullW = SECURE_CAMERA_WIDTH;
tempRect.fullH = SECURE_CAMERA_HEIGHT;
tempRect.colorFormat = V4L2_PIX_FMT_SBGGR8;
} else {
tempRect.fullW = VISION_WIDTH;
tempRect.fullH = VISION_HEIGHT;
tempRect.colorFormat = V4L2_PIX_FMT_SGRBG8;
}
#else
tempRect.fullW = maxSensorW + 16;
tempRect.fullH = maxSensorH + 10;
tempRect.colorFormat = bayerFormat;
#endif
pipeInfo[0].rectInfo = tempRect;
pipeInfo[0].bufInfo.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
pipeInfo[0].bufInfo.memory = V4L2_CAMERA_MEMORY_TYPE;
pipeInfo[0].bufInfo.count = FRONT_NUM_BAYER_BUFFERS;
/* per frame info */
pipeInfo[0].perFrameNodeGroupInfo.perframeSupportNodeNum = 0;
pipeInfo[0].perFrameNodeGroupInfo.perFrameLeaderInfo.perFrameNodeType = PERFRAME_NODE_TYPE_NONE;
ret = m_pipes[INDEX(PIPE_FLITE)]->setupPipe(pipeInfo, m_sensorIds[INDEX(PIPE_FLITE)]);
if (ret < 0) {
CLOGE("ERR(%s[%d]):FLITE setupPipe fail, ret(%d)", __FUNCTION__, __LINE__, ret);
/* TODO: exception handling */
return INVALID_OPERATION;
}
m_frameCount = 0;
return NO_ERROR;
}
status_t ExynosCameraFrameFactoryVision::preparePipes(void)
{
int ret = 0;
CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__);
ret = m_pipes[INDEX(PIPE_FLITE)]->prepare();
if (ret < 0) {
CLOGE("ERR(%s[%d]):FLITE prepare fail, ret(%d)", __FUNCTION__, __LINE__, ret);
/* TODO: exception handling */
return INVALID_OPERATION;
}
return NO_ERROR;
}
status_t ExynosCameraFrameFactoryVision::startPipes(void)
{
int ret = 0;
CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__);
ret = m_pipes[INDEX(PIPE_FLITE)]->start();
if (ret < 0) {
CLOGE("ERR(%s[%d]):FLITE start fail, ret(%d)", __FUNCTION__, __LINE__, ret);
/* TODO: exception handling */
return INVALID_OPERATION;
}
ret = m_pipes[INDEX(PIPE_FLITE)]->sensorStream(true);
if (ret < 0) {
CLOGE("ERR(%s[%d]):FLITE sensorStream on fail, ret(%d)", __FUNCTION__, __LINE__, ret);
/* TODO: exception handling */
return INVALID_OPERATION;
}
CLOGI("INFO(%s[%d]):Starting Front [FLITE] Success!", __FUNCTION__, __LINE__);
return NO_ERROR;
}
status_t ExynosCameraFrameFactoryVision::startInitialThreads(void)
{
int ret = 0;
CLOGI("INFO(%s[%d]):start pre-ordered initial pipe thread", __FUNCTION__, __LINE__);
ret = startThread(PIPE_FLITE);
if (ret < 0)
return ret;
return NO_ERROR;
}
status_t ExynosCameraFrameFactoryVision::stopPipes(void)
{
int ret = 0;
CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__);
ret = m_pipes[INDEX(PIPE_FLITE)]->sensorStream(false);
if (ret < 0) {
CLOGE("ERR(%s[%d]):FLITE sensorStream fail, ret(%d)", __FUNCTION__, __LINE__, ret);
/* TODO: exception handling */
return INVALID_OPERATION;
}
ret = m_pipes[INDEX(PIPE_FLITE)]->stop();
if (ret < 0) {
CLOGE("ERR(%s[%d]):FLITE stop fail, ret(%d)", __FUNCTION__, __LINE__, ret);
/* TODO: exception handling */
return INVALID_OPERATION;
}
CLOGI("INFO(%s[%d]):Stopping Front [FLITE] Success!", __FUNCTION__, __LINE__);
return NO_ERROR;
}
void ExynosCameraFrameFactoryVision::setRequest3AC(__unused bool enable)
{
/* Do nothing */
return;
}
void ExynosCameraFrameFactoryVision::m_init(void)
{
memset(m_nodeNums, -1, sizeof(m_nodeNums));
memset(m_sensorIds, -1, sizeof(m_sensorIds));
/* This seems all need to set 0 */
m_requestFLITE = 0;
m_request3AP = 0;
m_request3AC = 0;
m_requestISP = 1;
m_requestSCC = 0;
m_requestDIS = 0;
m_requestSCP = 1;
m_supportReprocessing = false;
m_flagFlite3aaOTF = false;
m_supportSCC = false;
m_supportPureBayerReprocessing = false;
m_flagReprocessing = false;
}
status_t ExynosCameraFrameFactoryVision::m_setupConfig(void)
{
CLOGI("INFO(%s[%d])", __FUNCTION__, __LINE__);
int32_t *nodeNums = NULL;
int32_t *controlId = NULL;
int32_t *prevNode = NULL;
bool enableSecure = false;
if (m_cameraId == CAMERA_ID_SECURE)
enableSecure = true;
nodeNums = m_nodeNums[INDEX(PIPE_FLITE)];
nodeNums[OUTPUT_NODE] = -1;
#ifdef SAMSUNG_TN_FEATURE
if (m_cameraId == CAMERA_ID_SECURE) {
nodeNums[CAPTURE_NODE_1] = SECURE_CAMERA_FLITE_NUM;
} else {
nodeNums[CAPTURE_NODE_1] = VISION_CAMERA_FLITE_NUM;
}
#else
nodeNums[CAPTURE_NODE_1] = FRONT_CAMERA_FLITE_NUM;
#endif
nodeNums[CAPTURE_NODE_2] = -1;
controlId = m_sensorIds[INDEX(PIPE_FLITE)];
controlId[CAPTURE_NODE_1] = m_getSensorId(nodeNums[CAPTURE_NODE_1], enableSecure);
prevNode = nodeNums;
return NO_ERROR;
}
#ifdef SAMSUNG_TN_FEATURE
int ExynosCameraFrameFactoryVision::m_getSensorId(__unused unsigned int nodeNum, bool enableSecure)
{
unsigned int scenarioBit = 0;
unsigned int nodeNumBit = 0;
unsigned int sensorIdBit = 0;
unsigned int sensorId = getSensorId(m_cameraId);
if (enableSecure == true)
scenarioBit = (SENSOR_SCENARIO_SECURE << SCENARIO_SHIFT);
else
scenarioBit = (SENSOR_SCENARIO_VISION << SCENARIO_SHIFT);
/*
* hack
* nodeNum - FIMC_IS_VIDEO_BAS_NUM is proper.
* but, historically, FIMC_IS_VIDEO_SS0_NUM - FIMC_IS_VIDEO_SS0_NUM is worked properly
*/
//nodeNumBit = ((nodeNum - FIMC_IS_VIDEO_BAS_NUM) << SSX_VINDEX_SHIFT);
nodeNumBit = ((FIMC_IS_VIDEO_SS0_NUM - FIMC_IS_VIDEO_SS0_NUM) << SSX_VINDEX_SHIFT);
sensorIdBit = (sensorId << 0);
return (scenarioBit) |
(nodeNumBit) |
(sensorIdBit);
}
#endif
}; /* namespace android */