blob: 60d291f33bbc76a199f2c462b965cfdf60feccfe [file] [log] [blame]
/*
* Copyright@ 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 "ExynosCameraPP"
#include "ExynosCameraPP.h"
ExynosCameraPP::~ExynosCameraPP()
{
SAFE_DELETE(m_nextPP);
}
status_t ExynosCameraPP::create(void)
{
status_t ret = NO_ERROR;
Mutex::Autolock lock(m_lock);
if (this->m_flagCreated() == true) {
CLOGE("It is already created. so, fail");
return INVALID_OPERATION;
}
ret = ExynosCameraPP::m_create();
if (ret != NO_ERROR) {
CLOGE("ExynosCameraPP::m_create() fail");
return INVALID_OPERATION;
}
ret = this->m_create();
if (ret != NO_ERROR) {
CLOGE("this->m_create() fail");
return INVALID_OPERATION;
}
m_flagCreate = true;
CLOGD("done");
return ret;
}
status_t ExynosCameraPP::destroy(void)
{
status_t ret = NO_ERROR;
status_t funcRet = NO_ERROR;
Mutex::Autolock lock(m_lock);
if (this->m_flagCreated() == false) {
CLOGE("It is not created. so, fail");
return INVALID_OPERATION;
}
ret = ExynosCameraPP::m_destroy();
funcRet |= ret;
if (ret != NO_ERROR) {
CLOGE("ExynosCameraPP::m_destroy() fail");
}
ret = this->m_destroy();
funcRet |= ret;
if (ret != NO_ERROR) {
CLOGE("this->m_destroy() fail");
}
/*
* destroy about nextPP.
* we don't need to call destroy() of m_nextPP's m_nextPP.
* because it will call destroy() automatically, reculsively.
*/
if (m_nextPP != NULL &&
m_nextPP->m_flagCreated() == true) {
ret = m_nextPP->destroy();
funcRet |= ret;
if (ret != NO_ERROR) {
CLOGE("m_nextPP(%s)->destroy() fail", m_nextPP->getName());
}
}
m_flagCreate = false;
CLOGD("done");
return funcRet;
}
bool ExynosCameraPP::flagCreated(void)
{
Mutex::Autolock lock(m_lock);
return m_flagCreated();
}
int ExynosCameraPP::getNodeNum(void)
{
return m_nodeNum;
}
ExynosCameraImageCapacity ExynosCameraPP::getSrcImageCapacity(void)
{
return m_srcImageCapacity;
}
ExynosCameraImageCapacity ExynosCameraPP::getDstImageCapacity(void)
{
return m_dstImageCapacity;
}
int ExynosCameraPP::getNumOfSrcImage(void)
{
return m_srcImageCapacity.getNumOfImage();
}
int ExynosCameraPP::getNumOfDstImage(void)
{
return m_dstImageCapacity.getNumOfImage();
}
bool ExynosCameraPP::isSupportedSrcImage(const int colorFormat, const int width = 1)
{
return m_srcImageCapacity.flagSupportedColorFormat(colorFormat, width);
}
bool ExynosCameraPP::isSupportedDstImage(const int colorFormat, const int width = 1)
{
return m_dstImageCapacity.flagSupportedColorFormat(colorFormat, width);
}
status_t ExynosCameraPP::setNextPP(ExynosCameraPP *pp)
{
if (m_nextPP != NULL) {
CLOGE("This PP(%s) already have m_nextPP(%s). so, fail", this->getName(), m_nextPP->getName());
return INVALID_OPERATION;
}
m_nextPP = pp;
return NO_ERROR;
}
ExynosCameraPP *ExynosCameraPP::getNextPP(void)
{
return m_nextPP;
}
status_t ExynosCameraPP::draw(ExynosCameraImage *srcImage,
ExynosCameraImage *dstImage)
{
status_t ret = NO_ERROR;
Mutex::Autolock lock(m_lock);
int numOfSrc = getNumOfSrcImage();
int numOfDst = getNumOfDstImage();
if (this->m_flagCreated() == false) {
CLOGE("It is not created. so, fail");
return INVALID_OPERATION;
}
ret = ExynosCameraPP::m_draw(srcImage, dstImage);
if (ret != NO_ERROR) {
CLOGE("ExynosCameraPP::m_draw(numOfSrc(%d), numOfDst(%d)] fail",
numOfSrc, numOfDst);
return INVALID_OPERATION;
}
ExynosCameraPP *pp = m_getProperPP(this, *srcImage, *dstImage);
if (pp == NULL) {
CLOGE("m_getProperPP() fail. so, just try the original this(%s)",
this->getName());
pp = this;
}
ret = pp->m_draw(srcImage, dstImage);
if (ret != NO_ERROR) {
char tempStr[EXYNOS_CAMERA_NAME_STR_SIZE];
snprintf(tempStr, EXYNOS_CAMERA_NAME_STR_SIZE,
"%s->m_draw(numOfSrc(%d), m_nodeNum(%d)):[SRC] fail",
pp->getName(), numOfSrc, pp->m_nodeNum);
pp->m_printImage(tempStr, numOfSrc, srcImage, true);
snprintf(tempStr, EXYNOS_CAMERA_NAME_STR_SIZE,
"%s->m_draw(numOfDst(%d), m_nodeNum(%d)):[DST] fail",
pp->getName(), numOfDst, pp->m_nodeNum);
pp->m_printImage(tempStr, numOfDst, dstImage, true);
return INVALID_OPERATION;
}
return ret;
}
status_t ExynosCameraPP::m_create(void)
{
status_t ret = NO_ERROR;
return ret;
}
status_t ExynosCameraPP::m_destroy(void)
{
status_t ret = NO_ERROR;
return ret;
}
bool ExynosCameraPP::m_flagCreated(void)
{
return m_flagCreate;
}
status_t ExynosCameraPP::m_draw(ExynosCameraImage *srcImage,
ExynosCameraImage *dstImage)
{
// we can debuging srcImage and dstImage.
char tempStr[EXYNOS_CAMERA_NAME_STR_SIZE];
snprintf(tempStr, EXYNOS_CAMERA_NAME_STR_SIZE, "draw():[SRC]");
m_printImage(tempStr, getNumOfSrcImage(), srcImage);
snprintf(tempStr, EXYNOS_CAMERA_NAME_STR_SIZE, "draw():[DST]");
m_printImage(tempStr, getNumOfDstImage(), dstImage);
return NO_ERROR;
}
ExynosCameraPP *ExynosCameraPP::m_getProperPP(ExynosCameraPP *pp,
ExynosCameraImage srcImage,
ExynosCameraImage dstImage)
{
ExynosCameraImageCapacity srcImageCapacity = pp->getSrcImageCapacity();
ExynosCameraImageCapacity dstImageCapacity = pp->getDstImageCapacity();
if (srcImageCapacity.flagSupportedColorFormat(srcImage.rect.colorFormat, srcImage.rect.fullW) == false ||
dstImageCapacity.flagSupportedColorFormat(dstImage.rect.colorFormat, dstImage.rect.fullW) == false) {
if (pp->m_nextPP != NULL) {
CLOGW("This %s send postprocessing to m_nextPP, to support [SRC]%c%c%c%c, fullW(%d) / [DST]%c%c%c%c, fullW(%d)",
m_name,
v4l2Format2Char(srcImage.rect.colorFormat, 0),
v4l2Format2Char(srcImage.rect.colorFormat, 1),
v4l2Format2Char(srcImage.rect.colorFormat, 2),
v4l2Format2Char(srcImage.rect.colorFormat, 3),
srcImage.rect.fullW,
v4l2Format2Char(dstImage.rect.colorFormat, 0),
v4l2Format2Char(dstImage.rect.colorFormat, 1),
v4l2Format2Char(dstImage.rect.colorFormat, 2),
v4l2Format2Char(dstImage.rect.colorFormat, 3),
dstImage.rect.fullW);
/*
* call reculsive function.
*/
return m_getProperPP(pp->m_nextPP, srcImage, dstImage);
} else {
char tempStr[EXYNOS_CAMERA_NAME_STR_SIZE];
if (srcImageCapacity.flagSupportedColorFormat(srcImage.rect.colorFormat, srcImage.rect.fullW) == false) {
snprintf(tempStr, EXYNOS_CAMERA_NAME_STR_SIZE, "This %s cannot support %c%c%c%c, fullW(%d) (m_nodeNum(%d)):[SRC]",
m_name,
v4l2Format2Char(srcImage.rect.colorFormat, 0),
v4l2Format2Char(srcImage.rect.colorFormat, 1),
v4l2Format2Char(srcImage.rect.colorFormat, 2),
v4l2Format2Char(srcImage.rect.colorFormat, 3),
srcImage.rect.fullW,
m_nodeNum);
m_printImage(tempStr, srcImage, true);
}
if (dstImageCapacity.flagSupportedColorFormat(dstImage.rect.colorFormat, dstImage.rect.fullH) == false) {
snprintf(tempStr, EXYNOS_CAMERA_NAME_STR_SIZE, "This %s cannot support %c%c%c%c, fullW(%d)(m_nodeNum(%d)):[DST]",
m_name,
v4l2Format2Char(dstImage.rect.colorFormat, 0),
v4l2Format2Char(dstImage.rect.colorFormat, 1),
v4l2Format2Char(dstImage.rect.colorFormat, 2),
v4l2Format2Char(dstImage.rect.colorFormat, 3),
dstImage.rect.fullW,
m_nodeNum);
m_printImage(tempStr, dstImage, true);
}
}
} else {
if (pp->m_flagCreated() == false) {
status_t ret = NO_ERROR;
ret = pp->create();
if (ret != NO_ERROR) {
CLOGE("pp(%s)->create() fail", pp->getName());
return NULL;
}
}
}
return pp;
}
void ExynosCameraPP::m_printImage(char *prefix, ExynosCameraImage image, bool flagLogd)
{
if (flagLogd == true) {
CLOGD("%s rect : x(%4d) y(%4d) w(%4d) h(%4d) fullW(%4d) rect.(%4d) colorFormat(%c%c%c%c)",
prefix,
image.rect.x,
image.rect.y,
image.rect.w,
image.rect.h,
image.rect.fullW,
image.rect.fullH,
v4l2Format2Char(image.rect.colorFormat, 0),
v4l2Format2Char(image.rect.colorFormat, 1),
v4l2Format2Char(image.rect.colorFormat, 2),
v4l2Format2Char(image.rect.colorFormat, 3));
CLOGD("%s buf : index(%2d) planeCount(%2d) : fd[0](%3d) fd[1](%3d) fd[2](%3d) : "
"addr[0](%p) addr[1](%p) addr[2](%p) : "
"size[0](%d) size[1](%d) size[2](%d)",
prefix,
image.buf.index,
image.buf.planeCount,
image.buf.fd[0],
image.buf.fd[1],
image.buf.fd[2],
image.buf.addr[0],
image.buf.addr[1],
image.buf.addr[2],
image.buf.size[0],
image.buf.size[1],
image.buf.size[2]);
CLOGD("%s info : rotation(%3d) flipH(%1d) flipV(%1d)",
prefix,
image.rotation,
image.flipH,
image.flipV);
} else {
CLOGV("%s rect : x(%4d) y(%4d) w(%4d) h(%4d) fullW(%4d) rect.(%4d) colorFormat(%c%c%c%c)",
prefix,
image.rect.x,
image.rect.y,
image.rect.w,
image.rect.h,
image.rect.fullW,
image.rect.fullH,
v4l2Format2Char(image.rect.colorFormat, 0),
v4l2Format2Char(image.rect.colorFormat, 1),
v4l2Format2Char(image.rect.colorFormat, 2),
v4l2Format2Char(image.rect.colorFormat, 3));
CLOGV("%s buf : index(%2d) planeCount(%2d) : fd[0](%3d) fd[1](%3d) fd[2](%3d) : "
"addr[0](%p) addr[1](%p) addr[2](%p) : "
"size[0](%d) size[1](%d) size[2](%d)",
prefix,
image.buf.index,
image.buf.planeCount,
image.buf.fd[0],
image.buf.fd[1],
image.buf.fd[2],
image.buf.addr[0],
image.buf.addr[1],
image.buf.addr[2],
image.buf.size[0],
image.buf.size[1],
image.buf.size[2]);
CLOGV("%s info : rotation(%3d) flipH(%1d) flipV(%1d)",
prefix,
image.rotation,
image.flipH,
image.flipV);
}
}
void ExynosCameraPP::m_printImage(char *prefix, int numOfImage, ExynosCameraImage *image, bool flagLogd)
{
for (int i = 0; i < numOfImage; i++) {
if (flagLogd == true) {
CLOGD("%s [%d] / [%d] rect : ", prefix, i, numOfImage);
m_printImage(prefix, image[i], flagLogd);
} else {
CLOGV("%s [%d] / [%d] rect : ", prefix, i, numOfImage);
// skip
// m_printImage(prefix, ExynosCameraImage image[i], flagLogd)
}
}
}
void ExynosCameraPP::m_init(void)
{
m_flagCreate = false;
m_cameraId = -1;
memset(m_name, 0x00, sizeof(m_name));
m_nodeNum = -1;
m_srcImageCapacity.setNumOfImage(1);
m_dstImageCapacity.setNumOfImage(1);
m_nextPP = NULL;
m_flagStarted = false;
}
status_t ExynosCameraPP::start(void)
{
status_t ret = NO_ERROR;
return ret;
}
status_t ExynosCameraPP::stop(__unused bool suspendFlag)
{
status_t ret = NO_ERROR;
return ret;
}
void ExynosCameraPP::setFlagStarted(bool flag)
{
m_flagStarted = flag;
}
bool ExynosCameraPP::getFlagStarted(void)
{
return m_flagStarted;
}