blob: 9bee6923f8236eb7dd69cf4431d8fe264b9125ea [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 "ExynosCameraUtils"
#include <log/log.h>
#include "ExynosCameraUtils.h"
#include <utils/CallStack.h>
#define ADD_BAYER_BY_NEON
namespace android {
status_t getCropRectAlign(
int src_w, int src_h,
int dst_w, int dst_h,
int *crop_x, int *crop_y,
int *crop_w, int *crop_h,
int align_w, int align_h,
int zoom, float zoomRatio)
{
*crop_w = src_w;
*crop_h = src_h;
if (src_w == 0 || src_h == 0 || dst_w == 0 || dst_h == 0) {
ALOGE("ERR(%s):width or height values is 0, src(%dx%d), dst(%dx%d)",
__func__, src_w, src_h, dst_w, dst_h);
return BAD_VALUE;
}
/* Calculation aspect ratio */
if ( src_w != dst_w
|| src_h != dst_h) {
float src_ratio = 1.0f;
float dst_ratio = 1.0f;
/* ex : 1024 / 768 */
src_ratio = ROUND_OFF_HALF(((float)src_w / (float)src_h), 2);
/* ex : 352 / 288 */
dst_ratio = ROUND_OFF_HALF(((float)dst_w / (float)dst_h), 2);
if (dst_ratio <= src_ratio) {
/* shrink w */
*crop_w = src_h * ((float)dst_w / (float)dst_h);
*crop_h = src_h;
} else {
/* shrink h */
*crop_w = src_w;
*crop_h = src_w / ((float)dst_w / (float)dst_h);
}
}
/* Calculation zoom */
if (zoom != 0) {
#if defined(SCALER_MAX_SCALE_UP_RATIO)
/*
* After dividing float & casting int,
* zoomed size can be smaller too much.
* so, when zoom until max, ceil up about floating point.
*/
if (((int)((float)*crop_w / zoomRatio)) * SCALER_MAX_SCALE_UP_RATIO < *crop_w ||
((int)((float)*crop_h / zoomRatio)) * SCALER_MAX_SCALE_UP_RATIO < *crop_h) {
*crop_w = (int)ceil(((float)*crop_w / zoomRatio));
*crop_h = (int)ceil(((float)*crop_h / zoomRatio));
} else
#endif
{
*crop_w = (int)((float)*crop_w / zoomRatio);
*crop_h = (int)((float)*crop_h / zoomRatio);
}
} else {
#ifdef SCALER_MAX_SCALE_UP_RATIO
if (*crop_w * SCALER_MAX_SCALE_UP_RATIO < dst_w
|| *crop_h * SCALER_MAX_SCALE_UP_RATIO < dst_h) {
int old_crop_w = 0;
int old_crop_h = 0;
old_crop_w = *crop_w;
old_crop_h = *crop_h;
*crop_w = (int)ceil((float)dst_w / SCALER_MAX_SCALE_UP_RATIO);
*crop_h = (int)ceil((float)dst_h / SCALER_MAX_SCALE_UP_RATIO);
ALOGD("DEBUG(%s[%d]):exceed max scaleup ratio : maxRatio(%d) old_crop(%d %d) new_crop(%d %d) dst(%d %d)",
__FUNCTION__, __LINE__, SCALER_MAX_SCALE_UP_RATIO, old_crop_w, old_crop_h, *crop_w, *crop_h, dst_w, dst_h);
}
#endif
}
if (dst_w == dst_h) {
int align_value = 0;
align_value = (align_w < align_h)? align_h : align_w;
*crop_w = ALIGN_UP(*crop_w, align_value);
*crop_h = ALIGN_UP(*crop_h, align_value);
if (*crop_w > src_w) {
*crop_w = ALIGN_DOWN(src_w, align_value);
*crop_h = *crop_w;
} else if (*crop_h > src_h) {
*crop_h = ALIGN_DOWN(src_h, align_value);
*crop_w = *crop_h;
}
} else {
*crop_w = ALIGN_UP(*crop_w, align_w);
*crop_h = ALIGN_UP(*crop_h, align_h);
if (*crop_w > src_w)
*crop_w = ALIGN_DOWN(src_w, align_w);
if (*crop_h > src_h)
*crop_h = ALIGN_DOWN(src_h, align_h);
}
*crop_x = ALIGN_DOWN(((src_w - *crop_w) >> 1), 2);
*crop_y = ALIGN_DOWN(((src_h - *crop_h) >> 1), 2);
if (*crop_x < 0 || *crop_y < 0) {
ALOGE("ERR(%s):crop size too big (%d, %d, %d, %d)",
__func__, *crop_x, *crop_y, *crop_w, *crop_h);
return BAD_VALUE;
}
return NO_ERROR;
}
status_t getCropRectAlign(
int src_w, int src_h,
int dst_w, int dst_h,
int *crop_x, int *crop_y,
int *crop_w, int *crop_h,
int align_w, int align_h,
float zoomRatio)
{
*crop_w = src_w;
*crop_h = src_h;
if (src_w == 0 || src_h == 0 || dst_w == 0 || dst_h == 0) {
ALOGE("ERR(%s):width or height values is 0, src(%dx%d), dst(%dx%d)",
__func__, src_w, src_h, dst_w, dst_h);
return BAD_VALUE;
}
/* Calculation aspect ratio */
if ( src_w != dst_w
|| src_h != dst_h) {
float src_ratio = 1.0f;
float dst_ratio = 1.0f;
/* ex : 1024 / 768 */
src_ratio = ROUND_OFF_HALF(((float)src_w / (float)src_h), 2);
/* ex : 352 / 288 */
dst_ratio = ROUND_OFF_HALF(((float)dst_w / (float)dst_h), 2);
if (dst_ratio <= src_ratio) {
/* shrink w */
*crop_w = src_h * ((float)dst_w / (float)dst_h);
*crop_h = src_h;
} else {
/* shrink h */
*crop_w = src_w;
*crop_h = src_w / ((float)dst_w / (float)dst_h);
}
}
/* Calculation zoom */
if (zoomRatio != 1.0f) {
#if defined(SCALER_MAX_SCALE_UP_RATIO)
/*
* After dividing float & casting int,
* zoomed size can be smaller too much.
* so, when zoom until max, ceil up about floating point.
*/
if (((int)((float)*crop_w / zoomRatio)) * SCALER_MAX_SCALE_UP_RATIO < *crop_w ||
((int)((float)*crop_h / zoomRatio)) * SCALER_MAX_SCALE_UP_RATIO < *crop_h) {
*crop_w = (int)ceil(((float)*crop_w / zoomRatio));
*crop_h = (int)ceil(((float)*crop_h / zoomRatio));
} else
#endif
{
*crop_w = (int)((float)*crop_w / zoomRatio);
*crop_h = (int)((float)*crop_h / zoomRatio);
}
}
if (dst_w == dst_h) {
int align_value = 0;
align_value = (align_w < align_h)? align_h : align_w;
*crop_w = ALIGN_UP(*crop_w, align_value);
*crop_h = ALIGN_UP(*crop_h, align_value);
if (*crop_w > src_w) {
*crop_w = ALIGN_DOWN(src_w, align_value);
*crop_h = *crop_w;
} else if (*crop_h > src_h) {
*crop_h = ALIGN_DOWN(src_h, align_value);
*crop_w = *crop_h;
}
} else {
*crop_w = ALIGN_UP(*crop_w, align_w);
*crop_h = ALIGN_UP(*crop_h, align_h);
if (*crop_w > src_w)
*crop_w = ALIGN_DOWN(src_w, align_w);
if (*crop_h > src_h)
*crop_h = ALIGN_DOWN(src_h, align_h);
}
*crop_x = ALIGN_DOWN(((src_w - *crop_w) >> 1), 2);
*crop_y = ALIGN_DOWN(((src_h - *crop_h) >> 1), 2);
if (*crop_x < 0 || *crop_y < 0) {
ALOGE("ERR(%s):crop size too big (%d, %d, %d, %d)",
__func__, *crop_x, *crop_y, *crop_w, *crop_h);
return BAD_VALUE;
}
return NO_ERROR;
}
uint32_t bracketsStr2Ints(
char *str,
uint32_t num,
ExynosRect2 *rect2s,
int *weights,
int mode)
{
char *curStr = str;
char buf[128];
char *bracketsOpen;
char *bracketsClose;
int tempArray[5] = {0,};
uint32_t validFocusedAreas = 0;
bool isValid;
bool nullArea = false;
isValid = true;
for (uint32_t i = 0; i < num + 1; i++) {
if (curStr == NULL) {
if (i != num) {
nullArea = false;
}
break;
}
bracketsOpen = strchr(curStr, '(');
if (bracketsOpen == NULL) {
if (i != num) {
nullArea = false;
}
break;
}
bracketsClose = strchr(bracketsOpen, ')');
if (bracketsClose == NULL) {
ALOGE("ERR(%s):subBracketsStr2Ints(%s) fail", __func__, buf);
if (i != num) {
nullArea = false;
}
break;
} else if (i == num) {
return 0;
}
strncpy(buf, bracketsOpen, bracketsClose - bracketsOpen + 1);
buf[bracketsClose - bracketsOpen + 1] = 0;
if (subBracketsStr2Ints(5, buf, tempArray) == false) {
nullArea = false;
break;
}
rect2s[i].x1 = tempArray[0];
rect2s[i].y1 = tempArray[1];
rect2s[i].x2 = tempArray[2];
rect2s[i].y2 = tempArray[3];
weights[i] = tempArray[4];
if (mode) {
isValid = true;
for (int j = 0; j < 4; j++) {
if (tempArray[j] < -1000 || tempArray[j] > 1000)
isValid = false;
}
if (tempArray[4] < 0 || tempArray[4] > 1000)
isValid = false;
if (!rect2s[i].x1 && !rect2s[i].y1 && !rect2s[i].x2 && !rect2s[i].y2 && !weights[i])
nullArea = true;
else if (weights[i] == 0)
isValid = false;
else if (!(tempArray[0] == 0 && tempArray[2] == 0) && tempArray[0] >= tempArray[2])
isValid = false;
else if (!(tempArray[1] == 0 && tempArray[3] == 0) && tempArray[1] >= tempArray[3])
isValid = false;
else if (!(tempArray[0] == 0 && tempArray[2] == 0) && (tempArray[1] == 0 && tempArray[3] == 0))
isValid = false;
else if ((tempArray[0] == 0 && tempArray[2] == 0) && !(tempArray[1] == 0 && tempArray[3] == 0))
isValid = false;
if (isValid)
validFocusedAreas++;
else
return 0;
} else {
if (rect2s[i].x1 || rect2s[i].y1 || rect2s[i].x2 || rect2s[i].y2 || weights[i])
validFocusedAreas++;
}
curStr = bracketsClose;
}
if (nullArea && mode)
validFocusedAreas = num;
if (validFocusedAreas == 0)
validFocusedAreas = 1;
ALOGD("DEBUG(%s[%d]):(%d,%d,%d,%d,%d) - validFocusedAreas(%d)", __FUNCTION__, __LINE__,
tempArray[0], tempArray[1], tempArray[2], tempArray[3], tempArray[4], validFocusedAreas);
return validFocusedAreas;
}
bool subBracketsStr2Ints(int num, char *str, int *arr)
{
if (str == NULL || arr == NULL) {
ALOGE("ERR(%s):str or arr is NULL", __func__);
return false;
}
/* ex : (-10,-10,0,0,300) */
char buf[128];
char *bracketsOpen;
char *bracketsClose;
char *tok;
char *savePtr;
bracketsOpen = strchr(str, '(');
if (bracketsOpen == NULL) {
ALOGE("ERR(%s):no '('", __func__);
return false;
}
bracketsClose = strchr(bracketsOpen, ')');
if (bracketsClose == NULL) {
ALOGE("ERR(%s):no ')'", __func__);
return false;
}
strncpy(buf, bracketsOpen + 1, bracketsClose - bracketsOpen + 1);
buf[bracketsClose - bracketsOpen + 1] = 0;
tok = strtok_r(buf, ",", &savePtr);
if (tok == NULL) {
ALOGE("ERR(%s):strtok_r(%s) fail", __func__, buf);
return false;
}
arr[0] = atoi(tok);
for (int i = 1; i < num; i++) {
tok = strtok_r(NULL, ",", &savePtr);
if (tok == NULL) {
if (i < num - 1) {
ALOGE("ERR(%s):strtok_r() (index : %d, num : %d) fail", __func__, i, num);
return false;
}
break;
}
arr[i] = atoi(tok);
}
return true;
}
void convertingRectToRect2(ExynosRect *rect, ExynosRect2 *rect2)
{
rect2->x1 = rect->x;
rect2->y1 = rect->y;
rect2->x2 = rect->x + rect->w - 1;
rect2->y2 = rect->y + rect->h - 1;
}
void convertingRect2ToRect(ExynosRect2 *rect2, ExynosRect *rect)
{
rect->x = rect2->x1;
rect->y = rect2->y1;
rect->w = rect2->x2 - rect2->x1 + 1;
rect->h = rect2->y2 - rect2->y1 + 1;
}
bool isRectNull(ExynosRect *rect)
{
if ( rect->x == 0
&& rect->y == 0
&& rect-> w == 0
&& rect->h == 0
&& rect->fullW == 0
&& rect->fullH == 0
&& rect->colorFormat == 0)
return true;
return false;
}
bool isRectNull(ExynosRect2 *rect2)
{
if ( rect2->x1 == 0
&& rect2->y1 == 0
&& rect2->x2 == 0
&& rect2->y2 == 0)
return true;
return false;
}
bool isRectEqual(ExynosRect *rect1, ExynosRect *rect2)
{
if ( rect1->x == rect2->x
&& rect1->y == rect2->y
&& rect1->w == rect2->w
&& rect1->h == rect2->h
&& rect1->fullW == rect2->fullW
&& rect1->fullH == rect2->fullH
&& rect1->colorFormat == rect2->colorFormat)
return true;
return false;
}
bool isRectEqual(ExynosRect2 *rect1, ExynosRect2 *rect2)
{
if ( rect1->x1 == rect2->x1
&& rect1->y1 == rect2->y1
&& rect1->x2 == rect2->x2
&& rect1->y2 == rect2->y2)
return true;
return false;
}
char v4l2Format2Char(int v4l2Format, int pos)
{
char c;
switch (pos) {
case 0:
c = (char)((v4l2Format >> 0) & 0xFF);
break;
case 1:
c = (char)((v4l2Format >> 8) & 0xFF);
break;
case 2:
c = (char)((v4l2Format >> 16) & 0xFF);
break;
case 3:
c = (char)((v4l2Format >> 24) & 0xFF);
break;
default:
c = ' ';
break;
}
return c;
}
ExynosRect2 convertingAndroidArea2HWArea(ExynosRect2 *srcRect, const ExynosRect *regionRect)
{
int w = regionRect->w;
int h = regionRect->h;
ExynosRect2 newRect2;
newRect2.x1 = (srcRect->x1 + 1000) * w / 2000;
newRect2.y1 = (srcRect->y1 + 1000) * h / 2000;
newRect2.x2 = (srcRect->x2 + 1000) * w / 2000;
newRect2.y2 = (srcRect->y2 + 1000) * h / 2000;
if (newRect2.x1 < 0)
newRect2.x1 = 0;
else if (w <= newRect2.x1)
newRect2.x1 = w - 1;
if (newRect2.y1 < 0)
newRect2.y1 = 0;
else if (h <= newRect2.y1)
newRect2.y1 = h - 1;
if (newRect2.x2 < 0)
newRect2.x2 = 0;
else if (w <= newRect2.x2)
newRect2.x2 = w - 1;
if (newRect2.y2 < 0)
newRect2.y2 = 0;
else if (h <= newRect2.y2)
newRect2.y2 = h - 1;
if (newRect2.x2 < newRect2.x1)
newRect2.x2 = newRect2.x1;
if (newRect2.y2 < newRect2.y1)
newRect2.y2 = newRect2.y1;
ALOGV("INFO(%s[%d]): src(%d %d %d %d) region(%d %d %d %d) newRect(%d %d %d %d)", __FUNCTION__, __LINE__,
srcRect->x1, srcRect->y1, srcRect->x2, srcRect->y2,
regionRect->x , regionRect->y, regionRect->w, regionRect->h,
newRect2.x1 , newRect2.y1, newRect2.x2, newRect2.y2);
return newRect2;
}
ExynosRect2 convertingAndroidArea2HWAreaBcropOut(ExynosRect2 *srcRect, const ExynosRect *regionRect)
{
/* do nothing, same as noraml converting */
return convertingAndroidArea2HWArea(srcRect, regionRect);
}
ExynosRect2 convertingHWArea2AndroidArea(ExynosRect2 *srcRect, ExynosRect *regionRect)
{
int w = regionRect->w;
int h = regionRect->h;
int min_val = -1000;
int max_val = 1000;
ExynosRect2 newRect2;
newRect2.x1 = ((srcRect->x1 * 2000) / w) - 1000;
newRect2.y1 = ((srcRect->y1 * 2000) / h) - 1000;
newRect2.x2 = ((srcRect->x2 * 2000) / w) - 1000;
newRect2.y2 = ((srcRect->y2 * 2000) / h) - 1000;
if (newRect2.x1 < min_val)
newRect2.x1 = min_val;
else if (max_val < newRect2.x1)
newRect2.x1 = max_val;
if (newRect2.y1 < min_val)
newRect2.y1 = min_val;
else if (max_val < newRect2.y1)
newRect2.y1 = max_val;
if (newRect2.x2 < min_val)
newRect2.x2 = min_val;
else if (max_val < newRect2.x2)
newRect2.x2 = max_val;
if (newRect2.y2 < min_val)
newRect2.y2 = min_val;
else if (max_val < newRect2.y2)
newRect2.y2 = max_val;
if (newRect2.x2 < newRect2.x1)
newRect2.x2 = newRect2.x1;
if (newRect2.y2 < newRect2.y1)
newRect2.y2 = newRect2.y1;
ALOGV("INFO(%s[%d]): src(%d %d %d %d) region(%d %d %d %d) newRect(%d %d %d %d)", __FUNCTION__, __LINE__,
srcRect->x1, srcRect->y1, srcRect->x2, srcRect->y2,
regionRect->x , regionRect->y, regionRect->w, regionRect->h,
newRect2.x1 , newRect2.y1, newRect2.x2, newRect2.y2);
return newRect2;
}
ExynosRect convertingBufferDst2Rect(ExynosCameraBuffer *buffer, int colorFormat)
{
ExynosRect rect;
camera2_stream *shot_stream = (camera2_stream *)buffer->addr[buffer->getMetaPlaneIndex()];
if (shot_stream == NULL) {
// assert? instead of ALOGE?
ALOGE("ERR(%s[%d]):shot_stream == NULL. so fail. just set 0", __FUNCTION__, __LINE__);
} else {
rect.x = shot_stream->output_crop_region[0];
rect.y = shot_stream->output_crop_region[1];
rect.w = shot_stream->output_crop_region[2];
rect.h = shot_stream->output_crop_region[3];
rect.fullW = shot_stream->output_crop_region[2];
rect.fullH = shot_stream->output_crop_region[3];
rect.colorFormat = colorFormat;
}
return rect;
}
int32_t getMetaDmRequestFrameCount(struct camera2_shot_ext *shot_ext)
{
if (shot_ext == NULL) {
ALOGE("ERR(%s[%d]): buffer is NULL", __FUNCTION__, __LINE__);
return -1;
}
return shot_ext->shot.dm.request.frameCount;
}
int32_t getMetaDmRequestFrameCount(struct camera2_dm *dm)
{
if (dm == NULL) {
ALOGE("ERR(%s[%d]): buffer is NULL", __FUNCTION__, __LINE__);
return -1;
}
return dm->request.frameCount;
}
void setMetaCtlAeTargetFpsRange(struct camera2_shot_ext *shot_ext, uint32_t min, uint32_t max)
{
if (shot_ext->shot.ctl.aa.aeTargetFpsRange[0] != min ||
shot_ext->shot.ctl.aa.aeTargetFpsRange[1] != max) {
ALOGI("INFO(%s):aeTargetFpsRange(min=%d, min=%d)", __FUNCTION__, min, max);
}
shot_ext->shot.ctl.aa.aeTargetFpsRange[0] = min;
shot_ext->shot.ctl.aa.aeTargetFpsRange[1] = max;
}
void getMetaCtlAeTargetFpsRange(struct camera2_shot_ext *shot_ext, uint32_t *min, uint32_t *max)
{
*min = shot_ext->shot.ctl.aa.aeTargetFpsRange[0];
*max = shot_ext->shot.ctl.aa.aeTargetFpsRange[1];
}
void setMetaCtlSensorFrameDuration(struct camera2_shot_ext *shot_ext, uint64_t duration)
{
shot_ext->shot.ctl.sensor.frameDuration = duration;
}
void getMetaCtlSensorFrameDuration(struct camera2_shot_ext *shot_ext, uint64_t *duration)
{
*duration = shot_ext->shot.ctl.sensor.frameDuration;
}
void setMetaCtlAeMode(struct camera2_shot_ext *shot_ext, enum aa_aemode aeMode)
{
if (shot_ext->shot.ctl.sensor.exposureTime == 0)
shot_ext->shot.ctl.aa.aeMode = aeMode;
}
void getMetaCtlAeMode(struct camera2_shot_ext *shot_ext, enum aa_aemode *aeMode)
{
*aeMode = shot_ext->shot.ctl.aa.aeMode;
}
void setMetaCtlAeLock(struct camera2_shot_ext *shot_ext, bool lock)
{
if (lock == true)
shot_ext->shot.ctl.aa.aeLock = AA_AE_LOCK_ON;
else
shot_ext->shot.ctl.aa.aeLock = AA_AE_LOCK_OFF;
}
void getMetaCtlAeLock(struct camera2_shot_ext *shot_ext, bool *lock)
{
if (shot_ext->shot.ctl.aa.aeLock == AA_AE_LOCK_OFF)
*lock = false;
else
*lock = true;
}
#ifdef USE_SUBDIVIDED_EV
void setMetaCtlExposureCompensationStep(struct camera2_shot_ext *shot_ext, float expCompensationStep)
{
shot_ext->shot.ctl.aa.vendor_aeExpCompensationStep = expCompensationStep;
}
#endif
void setMetaCtlExposureCompensation(struct camera2_shot_ext *shot_ext, int32_t expCompensation)
{
shot_ext->shot.ctl.aa.aeExpCompensation = expCompensation;
}
void getMetaCtlExposureCompensation(struct camera2_shot_ext *shot_ext, int32_t *expCompensation)
{
*expCompensation = shot_ext->shot.ctl.aa.aeExpCompensation;
}
void setMetaCtlExposureTime(struct camera2_shot_ext *shot_ext, uint64_t exposureTime)
{
if (exposureTime != 0) {
shot_ext->shot.ctl.aa.aeMode = AA_AEMODE_OFF;
setMetaCtlAeRegion(shot_ext, 0, 0, 0, 0, 0);
}
shot_ext->shot.ctl.sensor.exposureTime = exposureTime;
}
void getMetaCtlExposureTime(struct camera2_shot_ext *shot_ext, uint64_t *exposureTime)
{
*exposureTime = shot_ext->shot.ctl.sensor.exposureTime;
}
void setMetaCtlCaptureExposureTime(struct camera2_shot_ext *shot_ext, uint32_t exposureTime)
{
shot_ext->shot.ctl.aa.vendor_captureExposureTime = exposureTime;
}
void getMetaCtlCaptureExposureTime(struct camera2_shot_ext *shot_ext, uint32_t *exposureTime)
{
*exposureTime = shot_ext->shot.ctl.aa.vendor_captureExposureTime;
}
#ifdef SUPPORT_DEPTH_MAP
void setMetaCtlDisparityMode(struct camera2_shot_ext *shot_ext, enum camera2_disparity_mode disparity_mode)
{
shot_ext->shot.uctl.isModeUd.disparity_mode = disparity_mode;
}
#endif
void setMetaCtlWbLevel(struct camera2_shot_ext *shot_ext, int32_t wbLevel)
{
shot_ext->shot.ctl.aa.vendor_awbValue = wbLevel;
}
void getMetaCtlWbLevel(struct camera2_shot_ext *shot_ext, int32_t *wbLevel)
{
*wbLevel = shot_ext->shot.ctl.aa.vendor_awbValue;
}
#ifdef USE_FW_ZOOMRATIO
void setMetaCtlZoom(struct camera2_shot_ext *shot_ext, float data)
{
shot_ext->shot.uctl.zoomRatio = data;
}
void getMetaCtlZoom(struct camera2_shot_ext *shot_ext, float *data)
{
*data = shot_ext->shot.uctl.zoomRatio;
}
#endif
status_t setMetaCtlCropRegion(
struct camera2_shot_ext *shot_ext,
int x, int y, int w, int h)
{
shot_ext->shot.ctl.scaler.cropRegion[0] = x;
shot_ext->shot.ctl.scaler.cropRegion[1] = y;
shot_ext->shot.ctl.scaler.cropRegion[2] = w;
shot_ext->shot.ctl.scaler.cropRegion[3] = h;
return NO_ERROR;
}
status_t setMetaCtlCropRegion(
struct camera2_shot_ext *shot_ext,
int zoom,
int srcW, int srcH,
int dstW, int dstH, float zoomRatio)
{
int newX = 0;
int newY = 0;
int newW = 0;
int newH = 0;
if (getCropRectAlign(srcW, srcH,
dstW, dstH,
&newX, &newY,
&newW, &newH,
16, 2,
zoom, zoomRatio) != NO_ERROR) {
ALOGE("ERR(%s):getCropRectAlign(%d, %d, %d, %d) fail",
__func__, srcW, srcH, dstW, dstH);
return BAD_VALUE;
}
newX = ALIGN(newX, 2);
newY = ALIGN(newY, 2);
ALOGV("DEBUG(%s):size(%d, %d, %d, %d), level(%d)",
__FUNCTION__, newX, newY, newW, newH, zoom);
shot_ext->shot.ctl.scaler.cropRegion[0] = newX;
shot_ext->shot.ctl.scaler.cropRegion[1] = newY;
shot_ext->shot.ctl.scaler.cropRegion[2] = newW;
shot_ext->shot.ctl.scaler.cropRegion[3] = newH;
return NO_ERROR;
}
void getMetaCtlCropRegion(
struct camera2_shot_ext *shot_ext,
int *x, int *y,
int *w, int *h)
{
*x = shot_ext->shot.ctl.scaler.cropRegion[0];
*y = shot_ext->shot.ctl.scaler.cropRegion[1];
*w = shot_ext->shot.ctl.scaler.cropRegion[2];
*h = shot_ext->shot.ctl.scaler.cropRegion[3];
}
void setMetaCtlAeRegion(
struct camera2_shot_ext *shot_ext,
int x, int y,
int w, int h,
int weight)
{
shot_ext->shot.ctl.aa.aeRegions[0] = x;
shot_ext->shot.ctl.aa.aeRegions[1] = y;
shot_ext->shot.ctl.aa.aeRegions[2] = w;
shot_ext->shot.ctl.aa.aeRegions[3] = h;
shot_ext->shot.ctl.aa.aeRegions[4] = weight;
}
void getMetaCtlAeRegion(
struct camera2_shot_ext *shot_ext,
int *x, int *y,
int *w, int *h,
int *weight)
{
*x = shot_ext->shot.ctl.aa.aeRegions[0];
*y = shot_ext->shot.ctl.aa.aeRegions[1];
*w = shot_ext->shot.ctl.aa.aeRegions[2];
*h = shot_ext->shot.ctl.aa.aeRegions[3];
*weight = shot_ext->shot.ctl.aa.aeRegions[4];
}
void setMetaCtlAntibandingMode(struct camera2_shot_ext *shot_ext, enum aa_ae_antibanding_mode antibandingMode)
{
shot_ext->shot.ctl.aa.aeAntibandingMode = antibandingMode;
}
void getMetaCtlAntibandingMode(struct camera2_shot_ext *shot_ext, enum aa_ae_antibanding_mode *antibandingMode)
{
*antibandingMode = shot_ext->shot.ctl.aa.aeAntibandingMode;
}
void setMetaCtlSceneMode(struct camera2_shot_ext *shot_ext, enum aa_mode mode, enum aa_scene_mode sceneMode)
{
enum processing_mode default_edge_mode = PROCESSING_MODE_FAST;
enum processing_mode default_noise_mode = PROCESSING_MODE_FAST;
int default_edge_strength = 5;
int default_noise_strength = 5;
shot_ext->shot.ctl.aa.mode = mode;
shot_ext->shot.ctl.aa.sceneMode = sceneMode;
switch (sceneMode) {
case AA_SCENE_MODE_FACE_PRIORITY:
if (shot_ext->shot.ctl.aa.aeMode == AA_AEMODE_OFF
&& shot_ext->shot.ctl.sensor.exposureTime == 0)
shot_ext->shot.ctl.aa.aeMode = AA_AEMODE_CENTER;
shot_ext->shot.ctl.aa.sceneMode = AA_SCENE_MODE_DISABLED;
if(shot_ext->shot.ctl.aa.vendor_isoMode != AA_ISOMODE_MANUAL) {
shot_ext->shot.ctl.aa.vendor_isoMode = AA_ISOMODE_AUTO;
shot_ext->shot.ctl.aa.vendor_isoValue = 0;
shot_ext->shot.ctl.sensor.sensitivity = 0;
}
shot_ext->shot.ctl.noise.mode = default_noise_mode;
shot_ext->shot.ctl.noise.strength = default_noise_strength;
shot_ext->shot.ctl.edge.mode = default_edge_mode;
shot_ext->shot.ctl.edge.strength = default_edge_strength;
shot_ext->shot.ctl.color.vendor_saturation = 3; /* "3" is default. */
break;
case AA_SCENE_MODE_ACTION:
if (shot_ext->shot.ctl.aa.aeMode == AA_AEMODE_OFF)
shot_ext->shot.ctl.aa.aeMode = AA_AEMODE_CENTER;
shot_ext->shot.ctl.aa.awbMode = AA_AWBMODE_WB_AUTO;
shot_ext->shot.ctl.aa.vendor_isoMode = AA_ISOMODE_AUTO;
shot_ext->shot.ctl.aa.vendor_isoValue = 0;
shot_ext->shot.ctl.sensor.sensitivity = 0;
shot_ext->shot.ctl.noise.mode = default_noise_mode;
shot_ext->shot.ctl.noise.strength = default_noise_strength;
shot_ext->shot.ctl.edge.mode = default_edge_mode;
shot_ext->shot.ctl.edge.strength = default_edge_strength;
shot_ext->shot.ctl.color.vendor_saturation = 3; /* "3" is default. */
break;
case AA_SCENE_MODE_PORTRAIT:
case AA_SCENE_MODE_LANDSCAPE:
/* set default setting */
if (shot_ext->shot.ctl.aa.aeMode == AA_AEMODE_OFF)
shot_ext->shot.ctl.aa.aeMode = AA_AEMODE_CENTER;
shot_ext->shot.ctl.aa.awbMode = AA_AWBMODE_WB_AUTO;
shot_ext->shot.ctl.aa.vendor_isoMode = AA_ISOMODE_AUTO;
shot_ext->shot.ctl.aa.vendor_isoValue = 0;
shot_ext->shot.ctl.sensor.sensitivity = 0;
shot_ext->shot.ctl.noise.mode = default_noise_mode;
shot_ext->shot.ctl.noise.strength = default_noise_strength;
shot_ext->shot.ctl.edge.mode = default_edge_mode;
shot_ext->shot.ctl.edge.strength = default_edge_strength;
shot_ext->shot.ctl.color.vendor_saturation = 3; /* "3" is default. */
break;
case AA_SCENE_MODE_NIGHT:
/* AE_LOCK is prohibited */
if (shot_ext->shot.ctl.aa.aeMode == AA_AEMODE_OFF ||
shot_ext->shot.ctl.aa.aeLock == AA_AE_LOCK_ON) {
shot_ext->shot.ctl.aa.aeMode = AA_AEMODE_CENTER;
}
shot_ext->shot.ctl.aa.awbMode = AA_AWBMODE_WB_AUTO;
shot_ext->shot.ctl.aa.vendor_isoMode = AA_ISOMODE_AUTO;
shot_ext->shot.ctl.aa.vendor_isoValue = 0;
shot_ext->shot.ctl.sensor.sensitivity = 0;
shot_ext->shot.ctl.noise.mode = default_noise_mode;
shot_ext->shot.ctl.noise.strength = default_noise_strength;
shot_ext->shot.ctl.edge.mode = default_edge_mode;
shot_ext->shot.ctl.edge.strength = default_edge_strength;
shot_ext->shot.ctl.color.vendor_saturation = 3; /* "3" is default. */
break;
case AA_SCENE_MODE_NIGHT_PORTRAIT:
case AA_SCENE_MODE_THEATRE:
case AA_SCENE_MODE_BEACH:
case AA_SCENE_MODE_SNOW:
/* set default setting */
if (shot_ext->shot.ctl.aa.aeMode == AA_AEMODE_OFF)
shot_ext->shot.ctl.aa.aeMode = AA_AEMODE_CENTER;
shot_ext->shot.ctl.aa.awbMode = AA_AWBMODE_WB_AUTO;
shot_ext->shot.ctl.aa.vendor_isoMode = AA_ISOMODE_AUTO;
shot_ext->shot.ctl.aa.vendor_isoValue = 0;
shot_ext->shot.ctl.sensor.sensitivity = 0;
shot_ext->shot.ctl.noise.mode = default_noise_mode;
shot_ext->shot.ctl.noise.strength = default_noise_strength;
shot_ext->shot.ctl.edge.mode = default_edge_mode;
shot_ext->shot.ctl.edge.strength = default_edge_strength;
shot_ext->shot.ctl.color.vendor_saturation = 3; /* "3" is default. */
break;
case AA_SCENE_MODE_SUNSET:
if (shot_ext->shot.ctl.aa.aeMode == AA_AEMODE_OFF)
shot_ext->shot.ctl.aa.aeMode = AA_AEMODE_CENTER;
shot_ext->shot.ctl.aa.awbMode = AA_AWBMODE_WB_DAYLIGHT;
shot_ext->shot.ctl.aa.vendor_isoMode = AA_ISOMODE_AUTO;
shot_ext->shot.ctl.aa.vendor_isoValue = 0;
shot_ext->shot.ctl.sensor.sensitivity = 0;
shot_ext->shot.ctl.noise.mode = default_noise_mode;
shot_ext->shot.ctl.noise.strength = default_noise_strength;
shot_ext->shot.ctl.edge.mode = default_edge_mode;
shot_ext->shot.ctl.edge.strength = default_edge_strength;
shot_ext->shot.ctl.color.vendor_saturation = 3; /* "3" is default. */
break;
case AA_SCENE_MODE_STEADYPHOTO:
case AA_SCENE_MODE_FIREWORKS:
case AA_SCENE_MODE_SPORTS:
/* set default setting */
if (shot_ext->shot.ctl.aa.aeMode == AA_AEMODE_OFF)
shot_ext->shot.ctl.aa.aeMode = AA_AEMODE_CENTER;
shot_ext->shot.ctl.aa.awbMode = AA_AWBMODE_WB_AUTO;
shot_ext->shot.ctl.aa.vendor_isoMode = AA_ISOMODE_AUTO;
shot_ext->shot.ctl.aa.vendor_isoValue = 0;
shot_ext->shot.ctl.sensor.sensitivity = 0;
shot_ext->shot.ctl.noise.mode = default_noise_mode;
shot_ext->shot.ctl.noise.strength = default_noise_strength;
shot_ext->shot.ctl.edge.mode = default_edge_mode;
shot_ext->shot.ctl.edge.strength = default_edge_strength;
shot_ext->shot.ctl.color.vendor_saturation = 3; /* "3" is default. */
break;
case AA_SCENE_MODE_PARTY:
if (shot_ext->shot.ctl.aa.aeMode == AA_AEMODE_OFF)
shot_ext->shot.ctl.aa.aeMode = AA_AEMODE_CENTER;
shot_ext->shot.ctl.aa.awbMode = AA_AWBMODE_WB_AUTO;
shot_ext->shot.ctl.aa.vendor_isoMode = AA_ISOMODE_MANUAL;
shot_ext->shot.ctl.aa.vendor_isoValue = 200;
shot_ext->shot.ctl.sensor.sensitivity = 200;
shot_ext->shot.ctl.noise.mode = default_noise_mode;
shot_ext->shot.ctl.noise.strength = default_noise_strength;
shot_ext->shot.ctl.edge.mode = default_edge_mode;
shot_ext->shot.ctl.edge.strength = default_edge_strength;
shot_ext->shot.ctl.color.vendor_saturation = 4; /* "4" is default + 1. */
break;
case AA_SCENE_MODE_CANDLELIGHT:
/* set default setting */
if (shot_ext->shot.ctl.aa.aeMode == AA_AEMODE_OFF)
shot_ext->shot.ctl.aa.aeMode = AA_AEMODE_CENTER;
shot_ext->shot.ctl.aa.awbMode = AA_AWBMODE_WB_AUTO;
shot_ext->shot.ctl.aa.vendor_isoMode = AA_ISOMODE_AUTO;
shot_ext->shot.ctl.aa.vendor_isoValue = 0;
shot_ext->shot.ctl.sensor.sensitivity = 0;
shot_ext->shot.ctl.noise.mode = default_noise_mode;
shot_ext->shot.ctl.noise.strength = default_noise_strength;
shot_ext->shot.ctl.edge.mode = default_edge_mode;
shot_ext->shot.ctl.edge.strength = default_edge_strength;
shot_ext->shot.ctl.color.vendor_saturation = 3; /* "3" is default. */
break;
#ifdef SAMSUNG_FOOD_MODE
case AA_SCENE_MODE_FOOD:
shot_ext->shot.ctl.aa.aeMode = AA_AEMODE_MATRIX;
shot_ext->shot.ctl.aa.awbMode = AA_AWBMODE_WB_AUTO;
shot_ext->shot.ctl.aa.vendor_isoMode = AA_ISOMODE_AUTO;
shot_ext->shot.ctl.aa.vendor_isoValue = 0;
shot_ext->shot.ctl.sensor.sensitivity = 0;
shot_ext->shot.ctl.noise.mode = default_noise_mode;
shot_ext->shot.ctl.noise.strength = default_noise_strength;
shot_ext->shot.ctl.edge.mode = default_edge_mode;
shot_ext->shot.ctl.edge.strength = default_edge_strength;
shot_ext->shot.ctl.color.vendor_saturation = 3; /* "3" is default. */
break;
#endif
case AA_SCENE_MODE_AQUA:
/* set default setting */
if (shot_ext->shot.ctl.aa.aeMode == AA_AEMODE_OFF)
shot_ext->shot.ctl.aa.aeMode = AA_AEMODE_CENTER;
shot_ext->shot.ctl.aa.awbMode = AA_AWBMODE_WB_AUTO;
shot_ext->shot.ctl.aa.vendor_isoMode = AA_ISOMODE_AUTO;
shot_ext->shot.ctl.aa.vendor_isoValue = 0;
shot_ext->shot.ctl.sensor.sensitivity = 0;
shot_ext->shot.ctl.noise.mode = default_noise_mode;
shot_ext->shot.ctl.noise.strength = default_noise_strength;
shot_ext->shot.ctl.edge.mode = default_edge_mode;
shot_ext->shot.ctl.edge.strength = default_edge_strength;
shot_ext->shot.ctl.color.vendor_saturation = 3; /* "3" is default. */
break;
default:
break;
}
}
void getMetaCtlSceneMode(struct camera2_shot_ext *shot_ext, enum aa_mode *mode, enum aa_scene_mode *sceneMode)
{
*mode = shot_ext->shot.ctl.aa.mode;
*sceneMode = shot_ext->shot.ctl.aa.sceneMode;
}
void setMetaCtlAwbMode(struct camera2_shot_ext *shot_ext, enum aa_awbmode awbMode)
{
shot_ext->shot.ctl.aa.awbMode = awbMode;
}
void getMetaCtlAwbMode(struct camera2_shot_ext *shot_ext, enum aa_awbmode *awbMode)
{
*awbMode = shot_ext->shot.ctl.aa.awbMode;
}
void setMetaCtlAwbLock(struct camera2_shot_ext *shot_ext, bool lock)
{
if (lock == true)
shot_ext->shot.ctl.aa.awbLock = AA_AWB_LOCK_ON;
else
shot_ext->shot.ctl.aa.awbLock = AA_AWB_LOCK_OFF;
}
void getMetaCtlAwbLock(struct camera2_shot_ext *shot_ext, bool *lock)
{
if (shot_ext->shot.ctl.aa.awbLock == AA_AWB_LOCK_OFF)
*lock = false;
else
*lock = true;
}
void setMetaVtMode(struct camera2_shot_ext *shot_ext, enum camera_vt_mode mode)
{
shot_ext->shot.uctl.vtMode = mode;
}
void setMetaVideoMode(struct camera2_shot_ext *shot_ext, enum aa_videomode mode)
{
shot_ext->shot.ctl.aa.vendor_videoMode = mode;
}
void setMetaCtlAfRegion(struct camera2_shot_ext *shot_ext,
int x, int y, int w, int h, int weight)
{
shot_ext->shot.ctl.aa.afRegions[0] = x;
shot_ext->shot.ctl.aa.afRegions[1] = y;
shot_ext->shot.ctl.aa.afRegions[2] = w;
shot_ext->shot.ctl.aa.afRegions[3] = h;
shot_ext->shot.ctl.aa.afRegions[4] = weight;
}
void getMetaCtlAfRegion(struct camera2_shot_ext *shot_ext,
int *x, int *y, int *w, int *h, int *weight)
{
*x = shot_ext->shot.ctl.aa.afRegions[0];
*y = shot_ext->shot.ctl.aa.afRegions[1];
*w = shot_ext->shot.ctl.aa.afRegions[2];
*h = shot_ext->shot.ctl.aa.afRegions[3];
*weight = shot_ext->shot.ctl.aa.afRegions[4];
}
void setMetaCtlColorCorrectionMode(struct camera2_shot_ext *shot_ext, enum colorcorrection_mode mode)
{
shot_ext->shot.ctl.color.mode = mode;
}
void getMetaCtlColorCorrectionMode(struct camera2_shot_ext *shot_ext, enum colorcorrection_mode *mode)
{
*mode = shot_ext->shot.ctl.color.mode;
}
void setMetaCtlAaEffect(struct camera2_shot_ext *shot_ext, aa_effect_mode_t mode)
{
shot_ext->shot.ctl.aa.effectMode = mode;
}
void getMetaCtlAaEffect(struct camera2_shot_ext *shot_ext, aa_effect_mode_t *mode)
{
*mode = shot_ext->shot.ctl.aa.effectMode;
}
void setMetaCtlBrightness(struct camera2_shot_ext *shot_ext, int32_t brightness)
{
shot_ext->shot.ctl.color.vendor_brightness = brightness;
}
void getMetaCtlBrightness(struct camera2_shot_ext *shot_ext, int32_t *brightness)
{
*brightness = shot_ext->shot.ctl.color.vendor_brightness;
}
void setMetaCtlSaturation(struct camera2_shot_ext *shot_ext, int32_t saturation)
{
shot_ext->shot.ctl.color.vendor_saturation = saturation;
}
void getMetaCtlSaturation(struct camera2_shot_ext *shot_ext, int32_t *saturation)
{
*saturation = shot_ext->shot.ctl.color.vendor_saturation;
}
void setMetaCtlHue(struct camera2_shot_ext *shot_ext, int32_t hue)
{
shot_ext->shot.ctl.color.vendor_hue = hue;
}
void getMetaCtlHue(struct camera2_shot_ext *shot_ext, int32_t *hue)
{
*hue = shot_ext->shot.ctl.color.vendor_hue;
}
void setMetaCtlContrast(struct camera2_shot_ext *shot_ext, uint32_t contrast)
{
shot_ext->shot.ctl.color.vendor_contrast = contrast;
}
void getMetaCtlContrast(struct camera2_shot_ext *shot_ext, uint32_t *contrast)
{
*contrast = shot_ext->shot.ctl.color.vendor_contrast;
}
void setMetaCtlSharpness(struct camera2_shot_ext *shot_ext, enum processing_mode edge_mode, int32_t edge_sharpness,
enum processing_mode noise_mode, int32_t noise_sharpness)
{
shot_ext->shot.ctl.edge.mode = edge_mode;
shot_ext->shot.ctl.edge.strength = (uint8_t) edge_sharpness;
shot_ext->shot.ctl.noise.mode = noise_mode;
shot_ext->shot.ctl.noise.strength = (uint8_t) noise_sharpness;
}
void getMetaCtlSharpness(struct camera2_shot_ext *shot_ext, enum processing_mode *edge_mode, int32_t *edge_sharpness,
enum processing_mode *noise_mode, int32_t *noise_sharpness)
{
*edge_mode = shot_ext->shot.ctl.edge.mode;
*edge_sharpness = (int32_t) shot_ext->shot.ctl.edge.strength;
*noise_mode = shot_ext->shot.ctl.noise.mode;
*noise_sharpness = (int32_t) shot_ext->shot.ctl.noise.strength;
}
void setMetaCtlIso(struct camera2_shot_ext *shot_ext, enum aa_isomode mode, uint32_t iso)
{
shot_ext->shot.ctl.aa.vendor_isoMode = mode;
shot_ext->shot.ctl.aa.vendor_isoValue = iso;
shot_ext->shot.ctl.sensor.sensitivity = iso;
}
void getMetaCtlIso(struct camera2_shot_ext *shot_ext, enum aa_isomode *mode, uint32_t *iso)
{
*mode = shot_ext->shot.ctl.aa.vendor_isoMode;
*iso = shot_ext->shot.ctl.aa.vendor_isoValue;
}
void setMetaCtlFdMode(struct camera2_shot_ext *shot_ext, enum facedetect_mode mode)
{
shot_ext->shot.ctl.stats.faceDetectMode = mode;
}
void setMetaUctlYsumPort(struct camera2_shot_ext *shot_ext, enum mcsc_port ysumPort)
{
shot_ext->shot.uctl.scalerUd.mcsc_sub_blk_port[INTERFACE_TYPE_YSUM] = ysumPort;
}
void getStreamFrameValid(struct camera2_stream *shot_stream, uint32_t *fvalid)
{
*fvalid = shot_stream->fvalid;
}
void getStreamFrameCount(struct camera2_stream *shot_stream, uint32_t *fcount)
{
*fcount = shot_stream->fcount;
}
status_t setMetaDmSensorTimeStamp(struct camera2_shot_ext *shot_ext, uint64_t timeStamp)
{
status_t status = NO_ERROR;
if (shot_ext == NULL) {
ALOGE("ERR(%s[%d]):buffer is NULL", __FUNCTION__, __LINE__);
status = INVALID_OPERATION;
return status;
}
shot_ext->shot.dm.sensor.timeStamp = timeStamp;
return status;
}
nsecs_t getMetaDmSensorTimeStamp(struct camera2_shot_ext *shot_ext)
{
if (shot_ext == NULL) {
ALOGE("ERR(%s[%d]):buffer is NULL", __FUNCTION__, __LINE__);
return 0;
}
return shot_ext->shot.dm.sensor.timeStamp;
}
status_t setMetaUdmSensorTimeStampBoot(struct camera2_shot_ext *shot_ext, uint64_t timeStamp)
{
status_t status = NO_ERROR;
if (shot_ext == NULL) {
ALOGE("ERR(%s[%d]):buffer is NULL", __FUNCTION__, __LINE__);
status = INVALID_OPERATION;
return status;
}
shot_ext->shot.udm.sensor.timeStampBoot = timeStamp;
return status;
}
nsecs_t getMetaUdmSensorTimeStampBoot(struct camera2_shot_ext *shot_ext)
{
if (shot_ext == NULL) {
ALOGE("ERR(%s[%d]):buffer is NULL", __FUNCTION__, __LINE__);
return 0;
}
return shot_ext->shot.udm.sensor.timeStampBoot;
}
void setMetaNodeLeaderRequest(struct camera2_shot_ext* shot_ext, int value)
{
shot_ext->node_group.leader.request = value;
ALOGV("INFO(%s[%d]):(%d)", __FUNCTION__, __LINE__,
shot_ext->node_group.leader.request);
}
void setMetaNodeLeaderVideoID(struct camera2_shot_ext* shot_ext, int value)
{
shot_ext->node_group.leader.vid = value;
ALOGV("INFO(%s[%d]):(%d)", __FUNCTION__, __LINE__,
shot_ext->node_group.leader.vid);
}
void setMetaNodeLeaderPixFormat(struct camera2_shot_ext* shot_ext, int value)
{
shot_ext->node_group.leader.pixelformat = value;
ALOGV("INFO(%s[%d]):(%d)", __FUNCTION__, __LINE__,
shot_ext->node_group.leader.pixelformat);
}
void setMetaNodeLeaderInputSize(struct camera2_shot_ext* shot_ext, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
{
shot_ext->node_group.leader.input.cropRegion[0] = x;
shot_ext->node_group.leader.input.cropRegion[1] = y;
shot_ext->node_group.leader.input.cropRegion[2] = w;
shot_ext->node_group.leader.input.cropRegion[3] = h;
ALOGV("INFO(%s[%d]):(%d, %d, %d, %d)", __FUNCTION__, __LINE__,
shot_ext->node_group.leader.input.cropRegion[0],
shot_ext->node_group.leader.input.cropRegion[1],
shot_ext->node_group.leader.input.cropRegion[2],
shot_ext->node_group.leader.input.cropRegion[3]);
}
void setMetaNodeLeaderOutputSize(struct camera2_shot_ext * shot_ext, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
{
shot_ext->node_group.leader.output.cropRegion[0] = x;
shot_ext->node_group.leader.output.cropRegion[1] = y;
shot_ext->node_group.leader.output.cropRegion[2] = w;
shot_ext->node_group.leader.output.cropRegion[3] = h;
ALOGV("INFO(%s[%d]):(%d, %d, %d, %d)", __FUNCTION__, __LINE__,
shot_ext->node_group.leader.output.cropRegion[0],
shot_ext->node_group.leader.output.cropRegion[1],
shot_ext->node_group.leader.output.cropRegion[2],
shot_ext->node_group.leader.output.cropRegion[3]);
}
void setMetaNodeCaptureRequest(struct camera2_shot_ext* shot_ext, int index, int value)
{
shot_ext->node_group.capture[index].request = value;
ALOGV("INFO(%s[%d]):(%d)(%d)", __FUNCTION__, __LINE__,
index,
shot_ext->node_group.capture[index].request);
}
void setMetaNodeCaptureVideoID(struct camera2_shot_ext* shot_ext, int index, int value)
{
shot_ext->node_group.capture[index].vid = value;
ALOGV("INFO(%s[%d]):(%d)(%d)", __FUNCTION__, __LINE__,
index,
shot_ext->node_group.capture[index].vid);
}
void setMetaNodeCapturePixFormat(struct camera2_shot_ext* shot_ext, int index, int value)
{
shot_ext->node_group.capture[index].pixelformat = value;
ALOGV("INFO(%s[%d]):(%d)(%d)", __FUNCTION__, __LINE__,
index,
shot_ext->node_group.capture[index].pixelformat);
}
void setMetaNodeCaptureInputSize(struct camera2_shot_ext* shot_ext, int index, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
{
shot_ext->node_group.capture[index].input.cropRegion[0] = x;
shot_ext->node_group.capture[index].input.cropRegion[1] = y;
shot_ext->node_group.capture[index].input.cropRegion[2] = w;
shot_ext->node_group.capture[index].input.cropRegion[3] = h;
ALOGV("INFO(%s[%d]):(%d)(%d, %d, %d, %d)", __FUNCTION__, __LINE__,
index,
shot_ext->node_group.capture[index].input.cropRegion[0],
shot_ext->node_group.capture[index].input.cropRegion[1],
shot_ext->node_group.capture[index].input.cropRegion[2],
shot_ext->node_group.capture[index].input.cropRegion[3]);
}
void setMetaNodeCaptureOutputSize(struct camera2_shot_ext * shot_ext, int index, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
{
shot_ext->node_group.capture[index].output.cropRegion[0] = x;
shot_ext->node_group.capture[index].output.cropRegion[1] = y;
shot_ext->node_group.capture[index].output.cropRegion[2] = w;
shot_ext->node_group.capture[index].output.cropRegion[3] = h;
ALOGV("INFO(%s[%d]):(%d)(%d, %d, %d, %d)", __FUNCTION__, __LINE__,
index,
shot_ext->node_group.capture[index].output.cropRegion[0],
shot_ext->node_group.capture[index].output.cropRegion[1],
shot_ext->node_group.capture[index].output.cropRegion[2],
shot_ext->node_group.capture[index].output.cropRegion[3]);
}
void setMetaBypassDrc(struct camera2_shot_ext *shot_ext, int value)
{
shot_ext->drc_bypass = value;
}
void setMetaBypassDis(struct camera2_shot_ext *shot_ext, int value)
{
shot_ext->dis_bypass = value;
}
void setMetaBypassDnr(struct camera2_shot_ext *shot_ext, int value)
{
shot_ext->dnr_bypass = value;
}
void setMetaBypassFd(struct camera2_shot_ext *shot_ext, int value)
{
shot_ext->fd_bypass = value;
}
void setMetaSetfile(struct camera2_shot_ext *shot_ext, int value)
{
shot_ext->setfile = value;
}
int mergeSetfileYuvRange(int setfile, int yuvRange)
{
int ret = setfile;
ret &= (0x0000ffff);
ret |= (yuvRange << 16);
return ret;
}
int getPlaneSizeFlite(int width, int height)
{
int PlaneSize;
int Alligned_Width;
int Bytes;
Alligned_Width = (width + 9) / 10 * 10;
Bytes = Alligned_Width * 8 / 5 ;
PlaneSize = Bytes * height;
return PlaneSize;
}
int getBayerLineSize(int width, int bayerFormat)
{
int bytesPerLine = 0;
if (width <= 0) {
ALOGE("ERR(%s[%d]):Invalid input width size (%d)", __FUNCTION__, __LINE__, width);
return bytesPerLine;
}
switch (bayerFormat) {
case V4L2_PIX_FMT_SBGGR16:
bytesPerLine = ROUND_UP(width * 2, CAMERA_16PX_ALIGN);
break;
case V4L2_PIX_FMT_SBGGR12:
bytesPerLine = ROUND_UP((width * 3 / 2), CAMERA_16PX_ALIGN);
break;
case V4L2_PIX_FMT_SBGGR10:
bytesPerLine = ROUND_UP((width * 5 / 4), CAMERA_16PX_ALIGN);
break;
case V4L2_PIX_FMT_SBGGR8:
case V4L2_PIX_FMT_SGRBG8:
bytesPerLine = ROUND_UP(width , CAMERA_16PX_ALIGN);
break;
default:
ALOGW("WRN(%s[%d]):Invalid bayer format(%d)", __FUNCTION__, __LINE__, bayerFormat);
bytesPerLine = ROUND_UP(width * 2, CAMERA_16PX_ALIGN);
break;
}
return bytesPerLine;
}
int getBayerPlaneSize(int width, int height, int bayerFormat)
{
int planeSize = 0;
int bytesPerLine = 0;
if (width <= 0 || height <= 0) {
ALOGE("ERR(%s[%d]):Invalid input size (%d x %d)", __FUNCTION__, __LINE__, width, height);
return planeSize;
}
bytesPerLine = getBayerLineSize(width, bayerFormat);
planeSize = bytesPerLine * height;
return planeSize;
}
bool directDumpToFile(ExynosCameraBuffer *buffer, uint32_t cameraId, uint32_t frameCount)
{
time_t rawtime;
struct tm* timeinfo;
FILE *file = NULL;
char fileName[EXYNOS_CAMERA_NAME_STR_SIZE];
if (buffer == NULL) {
ALOGE("Invalid ExynosBuffer");
return false;
}
if (buffer->addr[0] == NULL) {
ALOGE("Need to mmap the virtual address(%s)", buffer->bufMgrNm);
return false;
}
if (buffer->status.position == EXYNOS_CAMERA_BUFFER_POSITION_IN_DRIVER) {
ALOGE("Can't dump this buffer(%s, %d)", buffer->bufMgrNm, buffer->index);
return false;
}
for (int batchIndex = 0; batchIndex < buffer->batchSize; batchIndex++) {
/* skip meta plane */
int startPlaneIndex = batchIndex * (buffer->planeCount - 1);
int endPlaneIndex = (batchIndex + 1) * (buffer->planeCount - 1);
time(&rawtime);
timeinfo = localtime(&rawtime);
snprintf(fileName, sizeof(fileName), DEBUG_DUMP_NAME,
cameraId, buffer->bufMgrNm, frameCount, buffer->index, batchIndex,
timeinfo->tm_year+1900, timeinfo->tm_mon+1, timeinfo->tm_mday,
timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
file = fopen(fileName, "w");
if (file == NULL) {
ALOGE("ERR(%s):open(%s) fail", __func__, fileName);
return false;
}
fflush(stdout);
for (int plane = startPlaneIndex; plane < endPlaneIndex; plane++) {
fwrite(buffer->addr[plane], 1, buffer->size[plane], file);
ALOGI("filedump(%s, [%d]size(%d) s:%d, e:%d",
fileName, plane, buffer->size[plane],
startPlaneIndex, endPlaneIndex);
}
fflush(file);
fclose(file);
file = NULL;
ALOGD("filedump(%s) is successed!!", fileName);
}
return true;
}
bool dumpToFile(char *filename, char *srcBuf, unsigned int size)
{
FILE *yuvFd = NULL;
char *buffer = NULL;
yuvFd = fopen(filename, "w+");
if (yuvFd == NULL) {
ALOGE("ERR(%s):open(%s) fail",
__func__, filename);
return false;
}
buffer = (char *)malloc(size);
if (buffer == NULL) {
ALOGE("ERR(%s):malloc file", __func__);
fclose(yuvFd);
return false;
}
memcpy(buffer, srcBuf, size);
fflush(stdout);
fwrite(buffer, 1, size, yuvFd);
fflush(yuvFd);
if (yuvFd)
fclose(yuvFd);
if (buffer)
free(buffer);
ALOGD("DEBUG(%s):filedump(%s, size(%d) is successed!!",
__func__, filename, size);
return true;
}
bool dumpToFilePacked12(char *filename, char *srcBuf, unsigned int size)
{
FILE *yuvFd = NULL;
char *buffer = NULL;
unsigned int unpackedSize = 0;
yuvFd = fopen(filename, "w+");
if (yuvFd == NULL) {
ALOGE("ERR(%s):open(%s) fail",
__func__, filename);
return false;
}
unpackedSize = size * 4 / 3;
buffer = (char *)malloc(unpackedSize);
if (buffer == NULL) {
ALOGE("ERR(%s):malloc file", __func__);
fclose(yuvFd);
return false;
}
char packedPixel[3];
char unpackedPixel[4];
char *dstAddr = buffer;
memset(unpackedPixel, 0x00, sizeof(unpackedPixel));
/* TODO: Must consider buffer stride */
for (char *addr = srcBuf; addr < (srcBuf + size); addr += sizeof(packedPixel)) {
memcpy(packedPixel, addr, sizeof(packedPixel));
unpackedPixel[0] = packedPixel[0];
unpackedPixel[1] = packedPixel[1] & 0x0F;
unpackedPixel[2] = (packedPixel[1] & 0xF0) >> 4;
unpackedPixel[2] |= ((packedPixel[2] & 0x0F) << 4);
unpackedPixel[3] = (packedPixel[2] & 0xF0) >> 4;
memcpy(dstAddr, unpackedPixel, sizeof(unpackedPixel));
dstAddr += sizeof(unpackedPixel);
}
fflush(stdout);
fwrite(buffer, 1, unpackedSize, yuvFd);
fflush(yuvFd);
if (yuvFd)
fclose(yuvFd);
if (buffer)
free(buffer);
ALOGD("DEBUG(%s):filedump(%s, size(%d) is successed!!",
__func__, filename, size);
return true;
}
bool dumpToFile2plane(char *filename, char *srcBuf, char *srcBuf1, unsigned int size, unsigned int size1)
{
FILE *yuvFd = NULL;
char *buffer = NULL;
yuvFd = fopen(filename, "w+");
if (yuvFd == NULL) {
ALOGE("ERR(%s):open(%s) fail",
__func__, filename);
return false;
}
buffer = (char *)malloc(size + size1);
if (buffer == NULL) {
ALOGE("ERR(%s):malloc file", __func__);
fclose(yuvFd);
return false;
}
memcpy(buffer, srcBuf, size);
memcpy(buffer + size, srcBuf1, size1);
fflush(stdout);
fwrite(buffer, 1, size + size1, yuvFd);
fflush(yuvFd);
if (yuvFd)
fclose(yuvFd);
if (buffer)
free(buffer);
ALOGD("DEBUG(%s):filedump(%s, size(%d) is successed!!",
__func__, filename, size);
return true;
}
status_t readFromFile(char *fileName, char *dstBuf, uint32_t size)
{
status_t ret = NO_ERROR;
FILE *fd = NULL;
char *buffer = NULL;
size_t readSize = 0;
if (fileName == NULL || dstBuf == NULL || size == 0) {
ALOGE("ERR(%s):Invalid parameters. fileName %p dstBuf %p size %d",
__FUNCTION__, fileName, dstBuf, size);
return BAD_VALUE;
}
fd = fopen(fileName, "rb");
if (fd == NULL) {
ALOGE("ERR(%s):Failed to open %s",
__FUNCTION__, fileName);
return INVALID_OPERATION;
}
buffer = (char *) malloc(size);
if (buffer == NULL) {
ALOGE("ERR(%s):Failed to alloc buffer. size %u",
__FUNCTION__, size);
fclose(fd);
return INVALID_OPERATION;
}
readSize = fread(buffer, 1, size, fd);
if (readSize != size) {
ALOGW("WARN(%s):Image size mismatch! fileReadSize %zu bufferSize %u",
__FUNCTION__, readSize, size);
size = (size < readSize) ? size : readSize;
}
memcpy(dstBuf, buffer, size);
ALOGD("DEBUG(%s):Success to read %s. size %u",
__FUNCTION__, fileName, size);
if (buffer != NULL) {
free(buffer);
}
if (fd != NULL) {
fclose(fd);
}
return ret;
}
status_t getYuvPlaneSize(int format, unsigned int *size,
unsigned int width, unsigned int height,
camera_pixel_size pixelSize)
{
unsigned int frame_ratio = 1;
unsigned int frame_size = 0;
unsigned int src_bpp = 0;
unsigned int src_planes = 0;
if (getV4l2FormatInfo(format, &src_bpp, &src_planes, pixelSize) < 0){
ALOGE("ERR(%s[%d]): invalid format(%x)", __FUNCTION__, __LINE__, format);
return BAD_VALUE;
}
if (src_bpp == 0) {
ALOGE("ERR(%s[%d]): invalid bpp(%d), format %c%c%c%c",
__FUNCTION__, __LINE__, src_bpp,
v4l2Format2Char(format, 0),
v4l2Format2Char(format, 1),
v4l2Format2Char(format, 2),
v4l2Format2Char(format, 3));
return BAD_VALUE;
}
src_planes = (src_planes == 0) ? 1 : src_planes;
switch (pixelSize) {
case CAMERA_PIXEL_SIZE_8BIT:
frame_size = width * height;
frame_ratio = 8 * (src_planes - 1) / (src_bpp - 8);
break;
case CAMERA_PIXEL_SIZE_10BIT:
frame_size = (width * 2) * height;
frame_ratio = 16 * (src_planes - 1) / (src_bpp - 16);
break;
case CAMERA_PIXEL_SIZE_PACKED_10BIT:
case CAMERA_PIXEL_SIZE_8_2BIT:
frame_size = ALIGN_UP((unsigned int)((double)(width * 2) * (10.0 / 16.0)), CAMERA_16PX_ALIGN) * height;
frame_ratio = 10 * (src_planes - 1) / (src_bpp - 10);
break;
default:
ALOGE("ERR(%s[%d]): invalid pixel size number(%d)", __FUNCTION__, __LINE__, pixelSize);
return BAD_VALUE;
}
switch (src_planes) {
case 1:
switch (format) {
case V4L2_PIX_FMT_BGR32:
case V4L2_PIX_FMT_RGB32:
size[0] = frame_size << 2;
break;
case V4L2_PIX_FMT_RGB565X:
case V4L2_PIX_FMT_NV16:
case V4L2_PIX_FMT_NV61:
case V4L2_PIX_FMT_YUYV:
case V4L2_PIX_FMT_UYVY:
case V4L2_PIX_FMT_VYUY:
case V4L2_PIX_FMT_YVYU:
size[0] = frame_size << 1;
break;
case V4L2_PIX_FMT_YUV420:
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV21:
case V4L2_PIX_FMT_NV21M:
size[0] = (frame_size * 3) >> 1;
break;
case V4L2_PIX_FMT_YVU420:
size[0] = frame_size + (ALIGN((width >> 1), 16) * ((height >> 1) * 2));
break;
default:
ALOGE("%s::invalid color type", __func__);
return false;
break;
}
size[1] = 0;
size[2] = 0;
break;
case 2:
switch (format) {
case V4L2_PIX_FMT_NV12M_S10B:
size[0] = NV12M_Y_SIZE(width, height) + NV12M_Y_2B_SIZE(width, height);
size[1] = NV12M_CBCR_SIZE(width, height) + NV12M_CBCR_2B_SIZE(width, height);
size[2] = 0;
break;
case V4L2_PIX_FMT_NV16M_S10B:
size[0] = NV16M_Y_SIZE(width, height) + NV16M_Y_2B_SIZE(width, height);
size[1] = NV16M_CBCR_SIZE(width, height) + NV16M_CBCR_2B_SIZE(width, height);
size[2] = 0;
break;
default:
size[0] = frame_size;
size[1] = frame_size / frame_ratio;
size[2] = 0;
break;
}
break;
case 3:
size[0] = frame_size;
size[1] = frame_size / frame_ratio;
size[2] = frame_size / frame_ratio;
break;
default:
ALOGE("%s::invalid color foarmt", __func__);
return false;
break;
}
return NO_ERROR;
}
status_t getV4l2FormatInfo(unsigned int v4l2_pixel_format,
unsigned int *bpp, unsigned int *planes, camera_pixel_size pixelSize)
{
switch (v4l2_pixel_format) {
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV21:
*bpp = 12;
*planes = 1;
break;
case V4L2_PIX_FMT_NV12M:
case V4L2_PIX_FMT_NV21M:
case V4L2_PIX_FMT_NV12MT:
case V4L2_PIX_FMT_NV12MT_16X16:
*bpp = 12;
*planes = 2;
break;
case V4L2_PIX_FMT_YUV420:
case V4L2_PIX_FMT_YVU420:
*bpp = 12;
*planes = 1;
break;
case V4L2_PIX_FMT_YUV420M:
case V4L2_PIX_FMT_YVU420M:
*bpp = 12;
*planes = 3;
break;
case V4L2_PIX_FMT_NV12M_P010:
*planes = 2;
if (pixelSize == CAMERA_PIXEL_SIZE_10BIT) {
*bpp = 24;
} else if (pixelSize == CAMERA_PIXEL_SIZE_PACKED_10BIT) {
*bpp = 15;
} else {
*bpp = 0;
}
break;
case V4L2_PIX_FMT_NV12M_S10B:
*bpp = 15;
*planes = 2;
break;
case V4L2_PIX_FMT_YUYV:
case V4L2_PIX_FMT_YVYU:
case V4L2_PIX_FMT_UYVY:
case V4L2_PIX_FMT_VYUY:
*planes = 1;
if (pixelSize == CAMERA_PIXEL_SIZE_8BIT) {
*bpp = 16;
} else if (pixelSize == CAMERA_PIXEL_SIZE_10BIT) { /* Y210 format */
*bpp = 32;
} else if (pixelSize == CAMERA_PIXEL_SIZE_PACKED_10BIT) { /* Y210 packed format */
*bpp = 20;
} else {
*bpp = 0;
}
break;
case V4L2_PIX_FMT_NV16:
case V4L2_PIX_FMT_NV61:
*bpp = 16;
*planes = 1;
break;
case V4L2_PIX_FMT_NV16M:
case V4L2_PIX_FMT_NV61M:
*bpp = 16;
*planes = 2;
break;
case V4L2_PIX_FMT_NV16M_P210:
*planes = 2;
if (pixelSize == CAMERA_PIXEL_SIZE_10BIT) {
*bpp = 32;
} else if (pixelSize == CAMERA_PIXEL_SIZE_PACKED_10BIT) {
*bpp = 20;
} else {
*bpp = 0;
}
break;
case V4L2_PIX_FMT_NV16M_S10B:
*bpp = 20;
*planes = 2;
break;
case V4L2_PIX_FMT_YUV422P:
*bpp = 16;
*planes = 3;
break;
case V4L2_PIX_FMT_SBGGR16:
*bpp = 16;
*planes = 1;
break;
case V4L2_PIX_FMT_SBGGR12:
*bpp = 12;
*planes = 1;
break;
case V4L2_PIX_FMT_SBGGR10:
*bpp = 10;
*planes = 1;
break;
case V4L2_PIX_FMT_SBGGR8:
case V4L2_PIX_FMT_SGRBG8:
*bpp = 8;
*planes = 1;
break;
case V4L2_PIX_FMT_Z16:
*bpp = 16;
*planes = 1;
break;
default:
return BAD_VALUE;
break;
}
return NO_ERROR;
}
int getYuvPlaneCount(unsigned int v4l2_pixel_format, camera_pixel_size pixelSize)
{
int ret = 0;
unsigned int bpp = 0;
unsigned int planeCnt = 0;
ret = getV4l2FormatInfo(v4l2_pixel_format, &bpp, &planeCnt, pixelSize);
if (ret < 0) {
ALOGE("ERR(%s[%d]): BAD_VALUE", __FUNCTION__, __LINE__);
return -1;
}
return planeCnt;
}
int displayExynosBuffer( ExynosCameraBuffer *buffer) {
ALOGD("-----------------------------------------------");
ALOGD(" buffer.index = %d ", buffer->index);
ALOGD(" buffer.planeCount = %d ", buffer->planeCount);
for(int i = 0 ; i < buffer->planeCount ; i++ ) {
ALOGD(" buffer.fd[%d] = %d ", i, buffer->fd[i]);
ALOGD(" buffer.size[%d] = %d ", i, buffer->size[i]);
ALOGD(" buffer.addr[%d] = %p ", i, buffer->addr[i]);
}
ALOGD("-----------------------------------------------");
return 0;
}
#ifdef SENSOR_NAME_GET_FROM_FILE
int getSensorIdFromFile(int camId)
{
FILE *fp = NULL;
int numread = -1;
char sensor_name[50];
int sensorName = -1;
bool ret = true;
if (camId == CAMERA_ID_BACK) {
fp = fopen(SENSOR_NAME_PATH_BACK, "r");
if (fp == NULL) {
ALOGE("ERR(%s[%d]):failed to open sysfs entry", __FUNCTION__, __LINE__);
goto err;
}
#if defined(SENSOR_NAME_PATH_SECURE)
} else if (camId == CAMERA_ID_SECURE) {
fp = fopen(SENSOR_NAME_PATH_SECURE, "r");
if (fp == NULL) {
ALOGE("ERR(%s[%d]):failed to open sysfs entry", __FUNCTION__, __LINE__);
goto err;
}
#endif
#ifdef USE_DUAL_CAMERA
} else if (camId == CAMERA_ID_BACK_1) {
fp = fopen(SENSOR_NAME_PATH_BACK_1, "r");
if (fp == NULL) {
ALOGE("ERR(%s[%d]):failed to open sysfs entry", __FUNCTION__, __LINE__);
goto err;
}
#endif
} else {
fp = fopen(SENSOR_NAME_PATH_FRONT, "r");
if (fp == NULL) {
ALOGE("ERR(%s[%d]):failed to open sysfs entry", __FUNCTION__, __LINE__);
goto err;
}
}
if (fgets(sensor_name, sizeof(sensor_name), fp) == NULL) {
ALOGE("ERR(%s[%d]):failed to read sysfs entry", __FUNCTION__, __LINE__);
goto err;
}
numread = strlen(sensor_name);
ALOGD("DEBUG(%s[%d]):Sensor name is %s(%d)", __FUNCTION__, __LINE__, sensor_name, numread);
/* TODO: strncmp for check sensor name, str is vendor specific sensor name
* ex)
* if (strncmp((const char*)sensor_name, "str", numread - 1) == 0) {
* sensorName = SENSOR_NAME_IMX135;
* }
*/
sensorName = atoi(sensor_name);
err:
if (fp != NULL)
fclose(fp);
return sensorName;
}
#endif
#ifdef SENSOR_FW_GET_FROM_FILE
const char *getSensorFWFromFile(struct ExynosCameraSensorInfoBase *info, int camId)
{
FILE *fp = NULL;
int numread = -1;
if (camId == CAMERA_ID_BACK) {
fp = fopen(SENSOR_FW_PATH_BACK, "r");
if (fp == NULL) {
ALOGE("ERR(%s[%d]):failed to open sysfs entry", __FUNCTION__, __LINE__);
goto err;
}
}
#ifdef USE_DUAL_CAMERA
else if (camId == CAMERA_ID_BACK_1) {
fp = fopen(SENSOR_FW_PATH_BACK_1, "r");
if (fp == NULL) {
ALOGE("ERR(%s[%d]):failed to open sysfs entry", __FUNCTION__, __LINE__);
goto err;
}
}
#endif
else {
fp = fopen(SENSOR_FW_PATH_FRONT, "r");
if (fp == NULL) {
ALOGE("ERR(%s[%d]):failed to open sysfs entry", __FUNCTION__, __LINE__);
goto err;
}
}
if (fgets(info->sensor_fw, sizeof(info->sensor_fw), fp) == NULL) {
ALOGE("ERR(%s[%d]):failed to read sysfs entry", __FUNCTION__, __LINE__);
goto err;
}
numread = strlen(info->sensor_fw);
ALOGD("DEBUG(%s[%d]):Sensor fw(len:%d) is %s", __FUNCTION__, __LINE__, numread, info->sensor_fw);
err:
if (fp != NULL)
fclose(fp);
return (const char *)info->sensor_fw;
}
#endif
int checkBit(unsigned int *target, int index)
{
int ret = 0;
if (*target & (1 << index)) {
ret = 1;
} else {
ret = 0;
}
return ret;
}
void clearBit(unsigned int *target, int index, bool isStatePrint)
{
*target = *target &~ (1 << index);
if (isStatePrint)
ALOGD("INFO(%s[%d]):(0x%x)", __FUNCTION__, __LINE__, *target);
}
void setBit(unsigned int *target, int index, bool isStatePrint)
{
*target = *target | (1 << index);
if (isStatePrint)
ALOGD("INFO(%s[%d]):(0x%x)", __FUNCTION__, __LINE__, *target);
}
void resetBit(unsigned int *target, int value, bool isStatePrint)
{
*target = value;
if (isStatePrint)
ALOGD("INFO(%s[%d]):(0x%x)", __FUNCTION__, __LINE__, *target);
}
status_t addBayerBuffer(struct ExynosCameraBuffer *srcBuf,
struct ExynosCameraBuffer *dstBuf,
__unused ExynosRect *dstRect,
#ifndef ADD_BAYER_BY_NEON
__unused
#endif
bool isPacked)
{
status_t ret = NO_ERROR;
if (srcBuf == NULL) {
ALOGE("ERR(%s[%d]):srcBuf == NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
/* assume bayer buffer is 0 */
if (srcBuf->size[0] != dstBuf->size[0])
ALOGW("WARN(%s[%d]):srcBuf->size[0] (%d)!= dstBuf->size[0](%d). weird",
__FUNCTION__, __LINE__, srcBuf->size[0], dstBuf->size[0]);
unsigned int copySize = (srcBuf->size[0] < dstBuf->size[0]) ? srcBuf->size[0] : dstBuf->size[0];
#ifdef ADD_BAYER_BY_NEON
if (isPacked == true)
ret = addBayerBufferByNeonPacked(srcBuf, dstBuf, dstRect, copySize);
else
ret = addBayerBufferByNeon(srcBuf, dstBuf, copySize);
#else
ret = addBayerBufferByCpu(srcBuf, dstBuf, copySize);
#endif
if (ret != NO_ERROR)
ALOGE("ERR(%s[%d]):addBayerBuffer() fail", __FUNCTION__, __LINE__);
return ret;
}
status_t addBayerBufferByNeon(struct ExynosCameraBuffer *srcBuf,
struct ExynosCameraBuffer *dstBuf,
unsigned int copySize)
{
if (srcBuf->addr[0] == NULL) {
ALOGE("ERR(%s[%d]):srcBuf->addr[0] == NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
if (dstBuf->addr[0] == NULL) {
ALOGE("ERR(%s[%d]):dstBuf->addr[0] == NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
/* bayer is max 16bit, so add by short */
unsigned short*firstSrcAddr = (unsigned short *)srcBuf->addr[0];
unsigned short*firstDstAddr = (unsigned short *)dstBuf->addr[0];
unsigned short*srcAddr = firstSrcAddr;
unsigned short*dstAddr = firstDstAddr;
/*
* loop as copySize / 32 byte
* 32 byte is perfect align size of cache.
* 64 byte is not faster than 32byte.
*/
unsigned int alignByte = 64;
unsigned int alignShort = 32;
unsigned int realCopySize = copySize / alignByte;
unsigned int remainedCopySize = copySize % alignByte;
ALOGD("DEBUG(%s[%d]):srcAddr(%p), dstAddr(%p), copySize(%d), sizeof(short)(%zu),\
alignByte(%d), realCopySize(%d), remainedCopySize(%d)",
__FUNCTION__, __LINE__, srcAddr, dstAddr, copySize, sizeof(short), alignByte,
realCopySize, remainedCopySize);
unsigned short* src0_ptr, *src1_ptr;
uint16x8_t src0_u16x8_0;
uint16x8_t src0_u16x8_1;
uint16x8_t src0_u16x8_2;
uint16x8_t src0_u16x8_3;
src0_ptr = dstAddr;
src1_ptr = srcAddr;
for (unsigned int i = 0; i < realCopySize; i++) {
src0_u16x8_0 = vqaddq_u16(vshlq_n_u16(vld1q_u16((uint16_t*)(src0_ptr)), 6),
vshlq_n_u16(vld1q_u16((uint16_t*)(src1_ptr)), 6));
src0_u16x8_1 = vqaddq_u16(vshlq_n_u16(vld1q_u16((uint16_t*)(src0_ptr + 8)), 6),
vshlq_n_u16(vld1q_u16((uint16_t*)(src1_ptr + 8)), 6));
src0_u16x8_2 = vqaddq_u16(vshlq_n_u16(vld1q_u16((uint16_t*)(src0_ptr + 16)), 6),
vshlq_n_u16(vld1q_u16((uint16_t*)(src1_ptr + 16)), 6));
src0_u16x8_3 = vqaddq_u16(vshlq_n_u16(vld1q_u16((uint16_t*)(src0_ptr + 24)), 6),
vshlq_n_u16(vld1q_u16((uint16_t*)(src1_ptr + 24)), 6));
vst1q_u16((src0_ptr), vshrq_n_u16(src0_u16x8_0, 6));
vst1q_u16((src0_ptr + 8), vshrq_n_u16(src0_u16x8_1, 6));
vst1q_u16((src0_ptr + 16),vshrq_n_u16(src0_u16x8_2, 6));
vst1q_u16((src0_ptr + 24),vshrq_n_u16(src0_u16x8_3, 6));
src0_ptr = firstDstAddr + (alignShort * (i + 1));
src1_ptr = firstSrcAddr + (alignShort * (i + 1));
}
for (unsigned int i = 0; i < remainedCopySize; i++) {
dstAddr[i] = SATURATING_ADD(dstAddr[i], srcAddr[i]);
}
return NO_ERROR;
}
status_t addBayerBufferByNeonPacked(struct ExynosCameraBuffer *srcBuf,
struct ExynosCameraBuffer *dstBuf,
ExynosRect *dstRect,
unsigned int copySize)
{
if (srcBuf->addr[0] == NULL) {
ALOGE("ERR(%s[%d]):srcBuf->addr[0] == NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
if (dstBuf->addr[0] == NULL) {
ALOGE("ERR(%s[%d]):dstBuf->addr[0] == NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
/* bayer is max 16bit, so add by short */
unsigned char *firstSrcAddr = (unsigned char *)srcBuf->addr[0];
unsigned char *firstDstAddr = (unsigned char *)dstBuf->addr[0];
unsigned char *srcAddr = firstSrcAddr;
unsigned char *dstAddr = firstDstAddr;
/*
* * loop as copySize / 32 byte
* * 32 byte is perfect align size of cache.
* * 64 byte is not faster than 32byte.
* */
unsigned int alignByte = 12;
unsigned int realCopySize = copySize / alignByte;
unsigned int remainedCopySize = copySize % alignByte;
uint16x8_t src_u16x8_0 = {0, 0, 0, 0, 0, 0, 0, 0};
uint16x8_t dst_u16x8_0 = {0, 0, 0, 0, 0, 0, 0, 0};
unsigned int width_byte = dstRect->w * 12 / 8;
width_byte = ALIGN_UP(width_byte, 16);
ALOGD("DEBUG(%s[%d]):srcAddr(%p), dstAddr(%p), copySize(%d), sizeof(short)(%d),\
alignByte(%d), realCopySize(%d), remainedCopySize(%d), pixel width(%d), pixel height(%d),\
16 aligned byte width(%d)",
__FUNCTION__, __LINE__, srcAddr, dstAddr, copySize, (int)sizeof(short),
alignByte, realCopySize, remainedCopySize, dstRect->w, dstRect->h, width_byte);
unsigned short dstPix_0, dstPix_1, dstPix_2, dstPix_3, dstPix_4, dstPix_5, dstPix_6, dstPix_7;
unsigned short srcPix_0, srcPix_1, srcPix_2, srcPix_3, srcPix_4, srcPix_5, srcPix_6, srcPix_7;
unsigned int col;
for (unsigned int row = 0; row < (unsigned int)dstRect->h; row++) {
for (col = 0; col + alignByte <= width_byte; col += alignByte) {
dstAddr = firstDstAddr + width_byte * row + col;
srcAddr = firstSrcAddr + width_byte * row + col;
unsigned short temp_0 = dstAddr[0];
unsigned short temp_1 = dstAddr[1];
unsigned short temp_cmbd = COMBINE_P0(temp_0, temp_1);
unsigned short temp_2 = dstAddr[2];
unsigned short temp_cmbd2 = COMBINE_P1(temp_1, temp_2);
dstPix_0 = temp_cmbd - 32;
dstPix_1 = temp_cmbd2 - 32;
temp_0 = dstAddr[3];
temp_1 = dstAddr[4];
temp_cmbd = COMBINE_P0(temp_0, temp_1);
temp_2 = dstAddr[5];
temp_cmbd2 = COMBINE_P1(temp_1, temp_2);
dstPix_2 = temp_cmbd - 32;
dstPix_3 = temp_cmbd2 - 32;
temp_0 = dstAddr[6];
temp_1 = dstAddr[7];
temp_cmbd = COMBINE_P0(temp_0, temp_1);
temp_2 = dstAddr[8];
temp_cmbd2 = COMBINE_P1(temp_1, temp_2);
dstPix_4 = temp_cmbd - 32;
dstPix_5 = temp_cmbd2 - 32;
temp_0 = dstAddr[9];
temp_1 = dstAddr[10];
temp_cmbd = COMBINE_P0(temp_0, temp_1);
temp_2 = dstAddr[11];
temp_cmbd2 = COMBINE_P1(temp_1, temp_2);
dstPix_6 = temp_cmbd - 32;
dstPix_7 = temp_cmbd2 - 32;
temp_0 = srcAddr[0];
temp_1 = srcAddr[1];
temp_cmbd = COMBINE_P0(temp_0, temp_1);
temp_2 = srcAddr[2];
temp_cmbd2 = COMBINE_P1(temp_1, temp_2);
srcPix_0 = temp_cmbd - 32;
srcPix_1 = temp_cmbd2 - 32;
temp_0 = srcAddr[3];
temp_1 = srcAddr[4];
temp_cmbd = COMBINE_P0(temp_0, temp_1);
temp_2 = srcAddr[5];
temp_cmbd2 = COMBINE_P1(temp_1, temp_2);
srcPix_2 = temp_cmbd - 32;
srcPix_3 = temp_cmbd2 - 32;
temp_0 = srcAddr[6];
temp_1 = srcAddr[7];
temp_cmbd = COMBINE_P0(temp_0, temp_1);
temp_2 = srcAddr[8];
temp_cmbd2 = COMBINE_P1(temp_1, temp_2);
srcPix_4 = temp_cmbd - 32;
srcPix_5 = temp_cmbd2 - 32;
temp_0 = srcAddr[9];
temp_1 = srcAddr[10];
temp_cmbd = COMBINE_P0(temp_0, temp_1);
temp_2 = srcAddr[11];
temp_cmbd2 = COMBINE_P1(temp_1, temp_2);
srcPix_6 = temp_cmbd - 32;
srcPix_7 = temp_cmbd2 - 32;
src_u16x8_0 = vsetq_lane_u16(srcPix_0, src_u16x8_0, 0);
src_u16x8_0 = vsetq_lane_u16(srcPix_1, src_u16x8_0, 1);
src_u16x8_0 = vsetq_lane_u16(srcPix_2, src_u16x8_0, 2);
src_u16x8_0 = vsetq_lane_u16(srcPix_3, src_u16x8_0, 3);
src_u16x8_0 = vsetq_lane_u16(srcPix_4, src_u16x8_0, 4);
src_u16x8_0 = vsetq_lane_u16(srcPix_5, src_u16x8_0, 5);
src_u16x8_0 = vsetq_lane_u16(srcPix_6, src_u16x8_0, 6);
src_u16x8_0 = vsetq_lane_u16(srcPix_7, src_u16x8_0, 7);
dst_u16x8_0 = vsetq_lane_u16(dstPix_0, dst_u16x8_0, 0);
dst_u16x8_0 = vsetq_lane_u16(dstPix_1, dst_u16x8_0, 1);
dst_u16x8_0 = vsetq_lane_u16(dstPix_2, dst_u16x8_0, 2);
dst_u16x8_0 = vsetq_lane_u16(dstPix_3, dst_u16x8_0, 3);
dst_u16x8_0 = vsetq_lane_u16(dstPix_4, dst_u16x8_0, 4);
dst_u16x8_0 = vsetq_lane_u16(dstPix_5, dst_u16x8_0, 5);
dst_u16x8_0 = vsetq_lane_u16(dstPix_6, dst_u16x8_0, 6);
dst_u16x8_0 = vsetq_lane_u16(dstPix_7, dst_u16x8_0, 7);
dst_u16x8_0 = vqaddq_u16(vshlq_n_u16(dst_u16x8_0, 6), vshlq_n_u16(src_u16x8_0, 6));
dst_u16x8_0 = vshrq_n_u16(dst_u16x8_0, 6);
dstPix_0 = vgetq_lane_u16(dst_u16x8_0, 0);
dstPix_1 = vgetq_lane_u16(dst_u16x8_0, 1);
dstPix_2 = vgetq_lane_u16(dst_u16x8_0, 2);
dstPix_3 = vgetq_lane_u16(dst_u16x8_0, 3);
dstPix_4 = vgetq_lane_u16(dst_u16x8_0, 4);
dstPix_5 = vgetq_lane_u16(dst_u16x8_0, 5);
dstPix_6 = vgetq_lane_u16(dst_u16x8_0, 6);
dstPix_7 = vgetq_lane_u16(dst_u16x8_0, 7);
dstAddr[0] = (unsigned char)(dstPix_0);
dstAddr[1] = (unsigned char)((COMBINE_P3(dstPix_0, dstPix_1)));
dstAddr[2] = (unsigned char)(dstPix_1 >> 4);
dstAddr[3] = (unsigned char)(dstPix_2);
dstAddr[4] = (unsigned char)((COMBINE_P3(dstPix_2, dstPix_3)));
dstAddr[5] = (unsigned char)(dstPix_3 >> 4);
dstAddr[6] = (unsigned char)(dstPix_4);
dstAddr[7] = (unsigned char)((COMBINE_P3(dstPix_4, dstPix_5)));
dstAddr[8] = (unsigned char)(dstPix_5 >> 4);
dstAddr[9] = (unsigned char)(dstPix_6);
dstAddr[10] = (unsigned char)((COMBINE_P3(dstPix_6, dstPix_7)));
dstAddr[11] = (unsigned char)(dstPix_7 >> 4);
}
}
#if 0
/* for the case of pixel width which is not a multiple of 8. The section of codes need to be verified */
for (unsigned int i = 0; i < remainedCopySize; i += 3) {
unsigned char temp_0 = dstAddr[0];
unsigned char temp_1 = dstAddr[1];
unsigned char temp_cmbd = COMBINE_P0(temp_0, temp_1);
unsigned char temp_2 = dstAddr[2];
unsigned char temp_cmbd2 = COMBINE_P1(temp_1, temp_2);
unsigned char dstPix_0 = temp_cmbd;
unsigned char dstPix_1 = temp_cmbd2;
temp_0 = srcAddr[0];
temp_1 = srcAddr[1];
temp_cmbd = COMBINE_P0(temp_0, temp_1);
temp_2 = srcAddr[2];
temp_cmbd2 = COMBINE_P1(temp_1, temp_2);
srcPix_0 = temp_cmbd;
srcPix_1 = temp_cmbd2;
dstPix_0 = SATURATING_ADD(dstPix_0, srcPix_0);
dstPix_1 = SATURATING_ADD(dstPix_1, srcPix_1);
dstAddr[0] = (unsigned char)(dstPix_0);
dstAddr[1] = (unsigned char)((COMBINE_P3(dstPix_0, dstPix_1)));
dstAddr[2] = (unsigned char)(dstPix_1 >> 4);
dstAddr += 3;
srcAddr += 3;
}
#endif
return NO_ERROR;
}
status_t addBayerBufferByCpu(struct ExynosCameraBuffer *srcBuf,
struct ExynosCameraBuffer *dstBuf,
unsigned int copySize)
{
if (srcBuf->addr[0] == NULL) {
ALOGE("ERR(%s[%d]):srcBuf->addr[0] == NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
if (dstBuf->addr[0] == NULL) {
ALOGE("ERR(%s[%d]):dstBuf->addr[0] == NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
/* bayer is max 16bit, so add by short */
unsigned short *firstSrcAddr = (unsigned short *)srcBuf->addr[0];
unsigned short *firstDstAddr = (unsigned short *)dstBuf->addr[0];
unsigned short *srcAddr = firstSrcAddr;
unsigned short *dstAddr = firstDstAddr;
/*
* loop as copySize / 32 byte
* 32 byte is perfect align size of cache.
* 64 byte is not faster than 32byte.
*/
unsigned int alignByte = 32;
unsigned int alignShort = 16;
unsigned int realCopySize = copySize / alignByte;
unsigned int remainedCopySize = copySize % alignByte;
ALOGD("DEBUG(%s[%d]):srcAddr(%p), dstAddr(%p), copySize(%d), sizeof(short)(%zu),\
alignByte(%d), realCopySize(%d), remainedCopySize(%d)",
__FUNCTION__, __LINE__, srcAddr, dstAddr, copySize, sizeof(short), alignByte,
realCopySize, remainedCopySize);
for (unsigned int i = 0; i < realCopySize; i++) {
dstAddr[0] = SATURATING_ADD(dstAddr[0], srcAddr[0]);
dstAddr[1] = SATURATING_ADD(dstAddr[1], srcAddr[1]);
dstAddr[2] = SATURATING_ADD(dstAddr[2], srcAddr[2]);
dstAddr[3] = SATURATING_ADD(dstAddr[3], srcAddr[3]);
dstAddr[4] = SATURATING_ADD(dstAddr[4], srcAddr[4]);
dstAddr[5] = SATURATING_ADD(dstAddr[5], srcAddr[5]);
dstAddr[6] = SATURATING_ADD(dstAddr[6], srcAddr[6]);
dstAddr[7] = SATURATING_ADD(dstAddr[7], srcAddr[7]);
dstAddr[8] = SATURATING_ADD(dstAddr[8], srcAddr[8]);
dstAddr[9] = SATURATING_ADD(dstAddr[9], srcAddr[9]);
dstAddr[10] = SATURATING_ADD(dstAddr[10], srcAddr[10]);
dstAddr[11] = SATURATING_ADD(dstAddr[11], srcAddr[11]);
dstAddr[12] = SATURATING_ADD(dstAddr[12], srcAddr[12]);
dstAddr[13] = SATURATING_ADD(dstAddr[13], srcAddr[13]);
dstAddr[14] = SATURATING_ADD(dstAddr[14], srcAddr[14]);
dstAddr[15] = SATURATING_ADD(dstAddr[15], srcAddr[15]);
// jump next 32bytes.
//srcAddr += alignShort;
//dstAddr += alignShort;
/* This is faster on compiler lever */
srcAddr = firstSrcAddr + (alignShort * (i + 1));
dstAddr = firstDstAddr + (alignShort * (i + 1));
}
for (unsigned int i = 0; i < remainedCopySize; i++) {
dstAddr[i] = SATURATING_ADD(dstAddr[i], srcAddr[i]);
}
return NO_ERROR;
}
char clip(int i)
{
if(i < 0)
return 0;
else if(i > 255)
return 255;
else
return i;
}
/*
** The only convertingYUYVtoRGB888() code is covered by BSD.
** URL from which the open source has been downloaded is
** http://www.mathworks.com/matlabcentral/fileexchange/26249-yuy2-to-rgb-converter/content/YUY2toRGB.zip
*/
void convertingYUYVtoRGB888(char *dstBuf, char *srcBuf, int width, int height)
{
int Y0, Y1, U, V, C0, C1, D, E;
for(int y = 0; y < height; y++) {
for(int x = 0; x < (width / 2); x++)
{
Y0 = srcBuf[(2 * y * width) + (4 * x)];
Y1 = srcBuf[(2 * y * width) + (4 * x) + 2];
U = srcBuf[(2 * y * width) + (4 * x) + 1];
V = srcBuf[(2 * y * width) + (4 * x) + 3];
C0 = Y0 - 16;
C1 = Y1 - 16;
D = U - 128;
E = V - 128;
dstBuf[6 * (x + (y * width / 2))] =
clip(((298 * C0) + (409 * E) + 128) >> 8); // R0
dstBuf[6 * (x + (y * width / 2)) + 1] =
clip(((298 * C0) - (100 * D) - (208 * E) + 128) >> 8); // G0
dstBuf[6 * (x + (y * width / 2)) + 2] =
clip(((298 * C0) + (516 * D) + 128) >> 8); // B0
dstBuf[6 * (x + (y * width / 2)) + 3] =
clip(((298 * C1) + (409 * E) + 128) >> 8); // R1
dstBuf[6 * (x + (y * width / 2)) + 4] =
clip(((298 * C1) - (100 * D) - (208 * E) + 128) >> 8); // G1
dstBuf[6 * (x + (y * width / 2)) + 5] =
clip(((298 * C1) + (516 * D) + 128) >> 8); // B1
}
}
}
int getFliteNodenum(int cameraId)
{
int fliteNodeNum = FIMC_IS_VIDEO_SS0_NUM;
switch (cameraId) {
case CAMERA_ID_BACK:
fliteNodeNum = MAIN_CAMERA_FLITE_NUM;
break;
case CAMERA_ID_FRONT:
fliteNodeNum = FRONT_CAMERA_FLITE_NUM;
break;
#ifdef USE_DUAL_CAMERA
case CAMERA_ID_BACK_1:
fliteNodeNum = MAIN_1_CAMERA_FLITE_NUM;
break;
case CAMERA_ID_FRONT_1:
fliteNodeNum = FRONT_1_CAMERA_FLITE_NUM;
break;
#endif
case CAMERA_ID_SECURE:
/*HACK : SECURE_CAMERA_FLITE_NUM is not defined, so use FIMC_IS_VIDEO_SS3_NUM */
fliteNodeNum = FIMC_IS_VIDEO_SS3_NUM;
break;
default:
android_printAssert(NULL, LOG_TAG, "ASSERT(%s[%d]):Unexpected cameraId(%d), assert!!!!",
__FUNCTION__, __LINE__, cameraId);
break;
}
return fliteNodeNum;
}
int getFliteCaptureNodenum(int cameraId, int fliteOutputNode)
{
if (fliteOutputNode <= 0) {
android_printAssert(NULL, LOG_TAG, "ASSERT(%s[%d]):cameraId(%d):Invalid fliteOutputNode(%d). assert!!!!",
__FUNCTION__, __LINE__, cameraId, fliteOutputNode);
}
int ouputIndex = 0;
int fliteCaptureNodeNum = 0;
ouputIndex = fliteOutputNode - FIMC_IS_VIDEO_BAS_NUM;
if (ouputIndex <= 0) {
android_printAssert(NULL, LOG_TAG, "ASSERT(%s[%d]):cameraId(%d):Invalid ouputIndex(%d). assert!!!!",
__FUNCTION__, __LINE__, cameraId, ouputIndex);
}
/*
* in case of fliteOutputNode is FIMC_IS_VIDEO_SS2_NUM(103))
* (FIMC_IS_VIDEO_SS1VC0_NUM(214) - FIMC_IS_VIDEO_SS0VC0_NUM(210)) * (3 - 1) = 4 * 2 = 8
* 8 + FIMC_IS_VIDEO_SS0VC0_NUM(210) = FIMC_IS_VIDEO_SS2VC0_NUM(218)
*/
fliteCaptureNodeNum = (FIMC_IS_VIDEO_SS1VC0_NUM - FIMC_IS_VIDEO_SS0VC0_NUM) * (ouputIndex - 1);
fliteCaptureNodeNum += FIMC_IS_VIDEO_SS0VC0_NUM;
if (FIMC_IS_VIDEO_MAX_NUM <= fliteCaptureNodeNum) {
android_printAssert(NULL, LOG_TAG, "ASSERT(%s[%d]):cameraId(%d):Invalid fliteCaptureNodeNum(%d) by fliteOutputNode(%d), ouputIndex(%d). assert!!!!",
__FUNCTION__, __LINE__, cameraId, fliteCaptureNodeNum, fliteOutputNode, ouputIndex);
}
return fliteCaptureNodeNum;
}
#ifdef SUPPORT_DEPTH_MAP
int getDepthVcNodeNum(int cameraId)
{
int depthVcNodeNum = FIMC_IS_VIDEO_SS0VC1_NUM;
depthVcNodeNum = (cameraId == CAMERA_ID_BACK) ? MAIN_CAMERA_DEPTH_VC_NUM : FRONT_CAMERA_DEPTH_VC_NUM;
return depthVcNodeNum;
}
#endif // SUPPORT_DEPTH_MAP
void checkAndroidVersion(void) {
char value[PROPERTY_VALUE_MAX] = {0};
char targetAndroidVersion[PROPERTY_VALUE_MAX] = {0};
snprintf(targetAndroidVersion, PROPERTY_VALUE_MAX, "%d.%d", TARGET_ANDROID_VER_MAJ, TARGET_ANDROID_VER_MIN);
property_get("ro.build.version.release", value, "0");
if (strncmp(targetAndroidVersion, value, PROPERTY_VALUE_MAX))
ALOGD("DEBUG(%s[%d]): Tartget Android version (%s), build version (%s)",
__FUNCTION__, __LINE__, targetAndroidVersion, value);
else
ALOGI("Andorid build version release %s", value);
}
int calibratePosition(int w, int new_w, int pos)
{
return (float)(pos * new_w) / (float)w;
}
status_t updateYsumBuffer(struct ysum_data *ysumdata, ExynosCameraBuffer *dstBuf)
{
ExynosVideoMeta *videoMeta = NULL;
if (ysumdata == NULL) {
ALOGE("ysumdata null");
return -BAD_VALUE;
}
if (dstBuf == NULL) {
ALOGE(" dstBuf null");
return -BAD_VALUE;
}
if (dstBuf->batchSize > 1) {
ALOGD("YSUM recording does not support batch mode. only works at 30, 60 fps.");
return NO_ERROR;
}
int videoMetaPlaneIndex = dstBuf->getMetaPlaneIndex() - 1;
if (dstBuf->size[videoMetaPlaneIndex] != EXYNOS_CAMERA_VIDEO_META_PLANE_SIZE) {
android_printAssert(NULL, LOG_TAG,
"ASSERT(%s):Invalid access to video met plane. planeIndex %d size %d",
__FUNCTION__, videoMetaPlaneIndex, dstBuf->size[videoMetaPlaneIndex]);
return -BAD_VALUE;
}
videoMeta = (ExynosVideoMeta *)dstBuf->addr[videoMetaPlaneIndex];
if (videoMeta == NULL) {
ALOGD("ysum buffer is null");
return INVALID_OPERATION;
}
videoMeta->eType = VIDEO_INFO_TYPE_YSUM_DATA;
videoMeta->data.enc.sYsumData.high = ysumdata->higher_ysum_value;
videoMeta->data.enc.sYsumData.low = ysumdata->lower_ysum_value;
ALOGV("%s: higher_ysum(%ud), lower_ysum(%ud)",
__FUNCTION__,
videoMeta->data.enc.sYsumData.high, videoMeta->data.enc.sYsumData.low);
return NO_ERROR;
}
#ifdef SAMSUNG_HDR10_RECORDING
status_t updateHDRBuffer(ExynosCameraBuffer *dstBuf)
{
ExynosVideoMeta *videoMeta = NULL;
int videoMetaPlaneIndex = dstBuf->getMetaPlaneIndex() - 1;
if (dstBuf->size[videoMetaPlaneIndex] != EXYNOS_CAMERA_VIDEO_META_PLANE_SIZE) {
android_printAssert(NULL, LOG_TAG,
"ASSERT(%s):Invalid access to video meta plane. planeIndex %d size %d",
__FUNCTION__, videoMetaPlaneIndex, dstBuf->size[videoMetaPlaneIndex]);
return -BAD_VALUE;
}
videoMeta = (ExynosVideoMeta *)dstBuf->addr[videoMetaPlaneIndex];
videoMeta->eType = VIDEO_INFO_TYPE_HDR_STATIC;
videoMeta->sHdrStaticInfo.mID = 0; /* structure defined by Google, so do not know the meaning of mID. */
videoMeta->sHdrStaticInfo.sType1.mR.x = 140;
videoMeta->sHdrStaticInfo.sType1.mR.y = 150;
videoMeta->sHdrStaticInfo.sType1.mG.x = 160;
videoMeta->sHdrStaticInfo.sType1.mG.y = 170;
videoMeta->sHdrStaticInfo.sType1.mB.x = 180;
videoMeta->sHdrStaticInfo.sType1.mB.y = 190;
videoMeta->sHdrStaticInfo.sType1.mW.x = 80;
videoMeta->sHdrStaticInfo.sType1.mW.y = 90;
videoMeta->sHdrStaticInfo.sType1.mMaxDisplayLuminance = 100;
videoMeta->sHdrStaticInfo.sType1.mMinDisplayLuminance = 50;
videoMeta->sHdrStaticInfo.sType1.mMaxContentLightLevel = 6;
videoMeta->sHdrStaticInfo.sType1.mMaxFrameAverageLightLevel = 7;
ALOGV("mId(%d), mR(x:%d, y:%d), mG(x:%d, y:%d), mB(x:%d, y:%d), mW(x:%d, y:%d)",
videoMeta->sHdrStaticInfo.mID,
videoMeta->sHdrStaticInfo.sType1.mR.x, videoMeta->sHdrStaticInfo.sType1.mR.y,
videoMeta->sHdrStaticInfo.sType1.mG.x, videoMeta->sHdrStaticInfo.sType1.mG.y,
videoMeta->sHdrStaticInfo.sType1.mB.x, videoMeta->sHdrStaticInfo.sType1.mB.y,
videoMeta->sHdrStaticInfo.sType1.mW.x, videoMeta->sHdrStaticInfo.sType1.mW.y);
ALOGV("DisplayLuminance(max: %d, min: %d), MaxContentLightLevel(%d), MaxFrameAverageLightLevel(%d)",
videoMeta->sHdrStaticInfo.sType1.mMaxDisplayLuminance,
videoMeta->sHdrStaticInfo.sType1.mMinDisplayLuminance,
videoMeta->sHdrStaticInfo.sType1.mMaxContentLightLevel,
videoMeta->sHdrStaticInfo.sType1.mMaxFrameAverageLightLevel);
return NO_ERROR;
}
#endif /* SAMSUNG_HDR10_RECORDING */
void getV4l2Name(char* colorName, size_t length, int colorFormat)
{
size_t index = 0;
if (colorName == NULL) {
ALOGE("colorName is NULL");
return;
}
for (index = 0; index < length-1; index++) {
colorName[index] = colorFormat & 0xff;
colorFormat = colorFormat >> 8;
}
colorName[index] = '\0';
}
void setPreviewProperty(bool on)
{
int ret = 0;
char value[5] = {0};
snprintf(value, sizeof(value), "%d", (on == true) ? 2 : 0);
ALOGD("DEBUG(%s[%d]):Set persist.sys.camera.preview %s",
__FUNCTION__, __LINE__, value);
ret = property_set("persist.sys.camera.preview", value);
if (ret < 0) {
ALOGE("ERR(%s[%d]):Failed to set persist.sys.camera.preview. ret %d",
__FUNCTION__, __LINE__, ret);
}
}
#ifdef CAMERA_GED_FEATURE
bool isFastenAeStableSupported(int cameraId)
{
bool ret = false;
if (cameraId == CAMERA_ID_BACK) {
ret = USE_FASTEN_AE_STABLE;
}
#ifdef USE_DUAL_CAMERA
else if (cameraId == CAMERA_ID_BACK_1) {
ret = USE_FASTEN_AE_STABLE;
}
#endif
else if (cameraId == CAMERA_ID_FRONT) {
ret = USE_FASTEN_AE_STABLE_FRONT;
}
else {
ALOGE("ERR(%s[%d]): unknown cameraID(%d)", __FUNCTION__, __LINE__, cameraId);
}
ALOGI("INFO(%s[%d]): cameraID(%d) USE_FASTEN_AE_STABLE (%s)", __FUNCTION__, __LINE__, cameraId, ret ? "enable" : "disable");
return ret;
}
#endif
}; /* namespace android */
#ifdef USE_INTERNAL_ALLOC_DEBUG
//NOTE: Can't use the default C++ map and list utilities incase of global new/delete operator overloading
using namespace std;
#define PRINT_CALLSTACK
static int alloc_cnt = 0;
android::Mutex m_myAllocLock;
android::Mutex m_AllocLock;
typedef struct myElm myElm_t;
struct myElm {
void *ptr;
int size;
int cnt;
};
typedef struct my_node my_node_t;
struct my_node {
my_node_t *next;
myElm_t elm;
};
my_node_t *used_list = NULL;
my_node_t *free_list = NULL;
static int used_cnt = 0;
static int myList_init = 0;
static int elm_size()
{
return alloc_cnt;
}
my_node_t *get_node()
{
my_node_t *node;
node = (my_node_t *)malloc(sizeof(my_node_t));
if (!node) {
ALOGE("[EXYNOS_CAMERA_ALLOC: %s: %d], failed to allocate", __FUNCTION__, __LINE__);
return NULL;
}
node->next = NULL;
node->elm.ptr = NULL;
node->elm.size = 0;
return node;
}
void insert_node(my_node_t **list, my_node_t *node)
{
m_myAllocLock.lock();
if (*list == NULL) {
*list = node;
goto insert_node_end;
}
node->next = *list;
*list = node;
insert_node_end:
m_myAllocLock.unlock();
}
my_node_t *delete_node(my_node_t *node, my_node_t *prev)
{
my_node_t *ret_node = NULL;
if (node == NULL) {
return NULL;
}
if (prev != NULL) {
prev->next = node->next;
ret_node = prev;
} else {
ret_node = node->next;
}
free(node);
return ret_node;
}
my_node_t *remove_node(my_node_t **list, void* ptr)
{
my_node_t *node;
my_node_t *ret_node;
my_node_t *prev = NULL;
myElm_t *elm = NULL;
m_myAllocLock.lock();
node = *list;
if (node && node->elm.ptr == ptr) {
*list = node->next;
goto remove_node_end;
}
while (node && node->elm.ptr != ptr) {
prev = node;
node = node->next;
}
if (node == NULL) {
ALOGE("[EXYNOS_CAMERA_ALLOC: %s : %d]: failed to find the elm->ptr[%p] to remove : alloc_cnt = %d",
__FUNCTION__, __LINE__, ptr, alloc_cnt);
} else if (prev) {
prev->next = node->next;
node->next = NULL;
}
remove_node_end:
m_myAllocLock.unlock();
return node;
}
my_node_t *get_free_node(my_node_t **list)
{
my_node_t *node;
myElm_t *elm = NULL;
m_myAllocLock.lock();
node = *list;
if (!node) {
node = get_node();
if (!node)
goto get_free_node_end;
}
*list = node->next;
node->next = NULL;
get_free_node_end:
m_myAllocLock.unlock();
return node;
}
int alloc_info_print(int flag)
{
my_node_t *node;
m_myAllocLock.lock();
ALOGI("[EXYNOS_CAMERA_ALLOC: %s : %d] : ALIVE MEMORY BLOCKS INFO -Start",
__FUNCTION__, __LINE__);
ALOGI("[EXYNOS_CAMERA_ALLOC: %s : %d] : %p : alloc_cnt %d used_cnt %d",
__FUNCTION__, __LINE__, used_list, alloc_cnt, used_cnt);
if (flag == 0) {
node = used_list;
} else {
node = free_list;
}
while(node) {
ALOGI("[EXYNOS_CAMERA_ALLOC: %s : %d] : %p : %d : %d", __FUNCTION__, __LINE__,
node->elm.ptr, node->elm.size, node->elm.cnt);
node = node->next;
}
ALOGI("[EXYNOS_CAMERA_ALLOC: %s : %d] : ALIVE MEMORY BLOCKS INFO -End",
__FUNCTION__, __LINE__);
m_myAllocLock.unlock();
return 0;
}
int print_stack() {
#ifdef PRINT_CALLSTACK
android::CallStack stack;
stack.update();
stack.log("ExynosCamera", ANDROID_LOG_ERROR, "ExynosCamera_CallStack");
#endif
return 0;
}
void * operator new(size_t size)
{
int cnt = 0;
my_node_t *node;
#ifdef ALLOC_INFO_DUMP
ALOGV("[EXYNOS_CAMERA_ALLOC: %s++ operator overloading: %d] %d : cnt = %d",
__FUNCTION__, __LINE__, size, elm_size());
#endif
android::Mutex::Autolock lock(m_AllocLock);
void * p = malloc(size);
if (!p) {
ALOGE("[EXYNOS_CAMERA_ALLOC: %s : %d] Failed to allocate", __FUNCTION__, __LINE__);
} else {
alloc_cnt++;
node = get_free_node(&free_list);
if (node) {
node->elm.ptr = p;
node->elm.size = size;
node->elm.cnt = elm_size();
node->next = NULL;
insert_node(&used_list, node);
used_cnt++;
} else {
ALOGE("[EXYNOS_CAMERA_ALLOC: %s : %d] Failed to get node for storing the alloc info : %d %d",
__FUNCTION__, __LINE__, alloc_cnt, used_cnt);
}
}
#ifdef ALLOC_INFO_DUMP
ALOGI("[EXYNOS_CAMERA_ALLOC: %s-- operator overloading: %d] %p : %d : cnt = %d",
__FUNCTION__, __LINE__, p, size, elm_size());
#endif
return p;
}
void operator delete(void * p)
{
my_node_t *node;
#ifdef ALLOC_INFO_DUMP
ALOGV("[EXYNOS_CAMERA_ALLOC: %s++ operator overloading: %d] %p : %d",
__FUNCTION__, __LINE__, p, elm_size());
#endif
android::Mutex::Autolock lock(m_AllocLock);
free(p);
alloc_cnt--;
node = remove_node(&used_list, p);
if (node) {
used_cnt--;
node->elm.ptr = NULL;
node->elm.size = 0;
node->elm.cnt = elm_size();
node->next = NULL;
insert_node(&free_list, node);
} else {
ALOGE("[EXYNOS_CAMERA_ALLOC: %s : %d] Seems..the pointer is invalid or already freed : [%p] : %d %d",
__FUNCTION__, __LINE__, p, alloc_cnt, used_cnt);
print_stack();
alloc_info_print(0);
//assert(false);
}
#ifdef ALLOC_INFO_DUMP
ALOGI("[EXYNOS_CAMERA_ALLOC : %s-- operator overloading: %d] %p : %d",
__FUNCTION__, __LINE__, p, elm_size());
#endif
return;
}
void * operator new[](size_t size)
{
int cnt = 0;
my_node_t *node;
#ifdef ALLOC_INFO_DUMP
ALOGV("[EXYNOS_CAMERA_ALLOC: %s++ operator overloading: %d] %d : cnt = %d",
__FUNCTION__, __LINE__, size, elm_size());
#endif
android::Mutex::Autolock lock(m_AllocLock);
void * p = malloc(size);
if (!p) {
ALOGE("[EXYNOS_CAMERA_ALLOC: %s : %d] Failed to allocate", __FUNCTION__, __LINE__);
} else {
alloc_cnt++;
node = get_free_node(&free_list);
if (node) {
node->elm.ptr = p;
node->elm.size = size;
node->elm.cnt = elm_size();
node->next = NULL;
insert_node(&used_list, node);
used_cnt++;
} else {
ALOGE("[EXYNOS_CAMERA_ALLOC: %s : %d] Failed to get node for storing the alloc info : %d %d",
__FUNCTION__, __LINE__, alloc_cnt, used_cnt);
}
}
#ifdef ALLOC_INFO_DUMP
ALOGI("[EXYNOS_CAMERA_ALLOC: %s-- operator overloading: %d] %p : %d : cnt = %d",
__FUNCTION__, __LINE__, p, size, elm_size());
#endif
return p;
}
void operator delete[](void * p)
{
my_node_t *node;
#ifdef ALLOC_INFO_DUMP
ALOGV("[EXYNOS_CAMERA_ALLOC : %s++ operator overloading: %d] %p : %d",
__FUNCTION__, __LINE__, p, elm_size());
#endif
android::Mutex::Autolock lock(m_AllocLock);
free(p);
alloc_cnt--;
node = remove_node(&used_list, p);
if (node) {
used_cnt--;
node->elm.ptr = NULL;
node->elm.size = 0;
node->elm.cnt = elm_size();
node->next = NULL;
insert_node(&free_list, node);
} else {
ALOGE("[EXYNOS_CAMERA_ALLOC: %s : %d] Seems..the pointer is invalid or already freed : [%p] : %d %d",
__FUNCTION__, __LINE__, p, alloc_cnt, used_cnt);
print_stack();
alloc_info_print(0);
//assert(false);
}
#ifdef ALLOC_INFO_DUMP
ALOGI("[EXYNOS_CAMERA_ALLOC: %s-- operator overloading: %d] %p : %d",
__FUNCTION__, __LINE__, p, elm_size());
#endif
return;
}
#endif