2025-05-10 21:49:39 +08:00

1455 lines
56 KiB
C++

/*
* IspParamsSplitter.h - Split ISP params to Left/Right ISP params
*
* Copyright (c) 2021 Rockchip 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.
*
* Author: Cody Xie <cody.xie@rock-chips.com>
*/
#include "IspParamsSplitter.h"
#include <utility>
#include "common/rk_isp20_hw.h"
#include "common/rkisp2-config.h"
#include "common/rkisp3-config.h"
#include "algos/ae/rk_aiq_types_ae_hw.h"
using namespace RkCam;
//#define DEBUG
#define MAX(a,b) (((a)>(b))?(a):(b))
namespace {
// Internal implementation to split submodule configs eg:
// * SplitIsp2xAeLittle
// * SplitIsp2xAeBig0
// * SplitIsp3xAeBig0
// Then a module can be an aggregation of submodules
// for example:
// SplitAecParams
// -> SplitIsp2xAeLittle
// -> SplitIsp3xAeBig0
/*********************************************/
/* Aec hwi splitter */
/*********************************************/
void SplitAecWeight(
u8* ori_weight,
u8* left_weight,
u8* right_weight,
WinSplitMode mode,
u8 wnd_num
) {
switch (mode) {
case LEFT_AND_RIGHT_MODE:
for (int i = 0; i < wnd_num; i++) {
for (int j = 0; j < wnd_num; j++) {
left_weight[i * wnd_num + j] = ori_weight[i * wnd_num + j / 2];
right_weight[i * wnd_num + j] = ori_weight[i * wnd_num + j / 2 + j % 2 + wnd_num / 2];
}
}
break;
case LEFT_MODE:
case RIGHT_MODE:
memcpy(left_weight, ori_weight, wnd_num * wnd_num * sizeof(u8));
memcpy(right_weight, ori_weight, wnd_num * wnd_num * sizeof(u8));
default:
break;
}
}
void SplitAecSubWin(
u8* subwin_en,
struct isp2x_window* ori_win,
struct isp2x_window* left_win,
struct isp2x_window* right_win,
IspParamsSplitter::Rectangle left_isp_rect_,
IspParamsSplitter::Rectangle right_isp_rect_,
WinSplitMode* mode
) {
for (int i = 0; i < ISP2X_RAWAEBIG_SUBWIN_NUM; i++) {
if (subwin_en[i] == 1) { //only when subwin is enabled, should split hwi params
if (ori_win[i].h_offs + ori_win[i].h_size <= left_isp_rect_.w) {
#ifdef DEBUG
printf("win locate in left isp\n");
#endif
mode[i] = LEFT_MODE;
left_win[i].h_offs = ori_win[i].h_offs;
left_win[i].h_size = ori_win[i].h_size;
left_win[i].v_offs = ori_win[i].v_offs;
left_win[i].v_size = ori_win[i].v_size;
right_win[i].h_offs = 0;
right_win[i].h_size = ori_win[i].h_size;
right_win[i].v_offs = ori_win[i].v_offs;
right_win[i].v_size = ori_win[i].v_size;
}
else if (ori_win[i].h_offs >= right_isp_rect_.x) {
#ifdef DEBUG
printf("win locate in right isp\n");
#endif
mode[i] = RIGHT_MODE;
//win only locate in right isp, actually stats of left isp would not be used
left_win[i].h_offs = 0;
left_win[i].h_size = ori_win[i].h_size;
left_win[i].v_offs = ori_win[i].v_offs;
left_win[i].v_size = ori_win[i].v_size;
right_win[i].h_offs = ori_win[i].h_offs - right_isp_rect_.x;
right_win[i].h_size = ori_win[i].h_size;
right_win[i].v_offs = ori_win[i].v_offs;
right_win[i].v_size = ori_win[i].v_size;
}
else {
#ifdef DEBUG
printf(" win locate at left&right isp\n");
#endif
mode[i] = LEFT_AND_RIGHT_MODE;
left_win[i].h_offs = ori_win[i].h_offs;
left_win[i].h_size = MAX(0, ((long)left_isp_rect_.w - (long)left_win[i].h_offs));
left_win[i].v_offs = ori_win[i].v_offs;
left_win[i].v_size = ori_win[i].v_size;
right_win[i].h_offs = left_win[i].h_offs + left_win[i].h_size - right_isp_rect_.x;
right_win[i].h_size = MAX(0, ((long)ori_win[i].h_size - (long)left_win[i].h_size));
right_win[i].v_offs = ori_win[i].v_offs;
right_win[i].v_size = ori_win[i].v_size;
}
}
}
}
void SplitAecCalcBlockSize(
struct isp2x_window* left_win,
struct isp2x_window* right_win,
u8 wnd_num,
IspParamsSplitter::Rectangle right_isp_rect_,
u16* block_h
) {
bool loop_en = true;
while (loop_en && *block_h > 0) {
left_win->h_size = *block_h * wnd_num;
right_win->h_offs = (left_win->h_size + left_win->h_offs > right_isp_rect_.x) ?
left_win->h_size + left_win->h_offs - right_isp_rect_.x : 0;
if (u32(right_win->h_offs + *block_h * wnd_num) > right_isp_rect_.w - 1) {
(*block_h)--;
}
else {
loop_en = false;
//if (*block_h % 2)
//(*block_h)--;
left_win->h_size = *block_h * wnd_num;
right_win->h_offs = (left_win->h_size + left_win->h_offs > right_isp_rect_.x) ?
left_win->h_size + left_win->h_offs - right_isp_rect_.x : 0;
right_win->h_offs = right_win->h_offs & 0xfffe;
right_win->h_size = *block_h * wnd_num;
}
}
}
void SplitAecWin(
isp2x_window* ori_win,
isp2x_window* left_win,
isp2x_window* right_win,
u8 wnd_num,
IspParamsSplitter::Rectangle left_isp_rect_,
IspParamsSplitter::Rectangle right_isp_rect_,
WinSplitMode* mode
) {
//win only locate in left isp, actually stats of right isp would not be used
if (ori_win->h_offs + ori_win->h_size <= left_isp_rect_.w) {
#ifdef DEBUG
printf("win locate in left isp\n");
#endif
*mode = LEFT_MODE;
left_win->h_offs = ori_win->h_offs;
left_win->h_size = ori_win->h_size;
left_win->v_offs = ori_win->v_offs;
left_win->v_size = ori_win->v_size;
right_win->h_offs = 0;
right_win->h_size = ori_win->h_size;
right_win->v_offs = ori_win->v_offs;
right_win->v_size = ori_win->v_size;
}
else if (ori_win->h_offs >= right_isp_rect_.x) {
#ifdef DEBUG
printf("win locate in right isp\n");
#endif
*mode = RIGHT_MODE;
//win only locate in right isp, actually stats of left isp would not be used
left_win->h_offs = 0;
left_win->h_size = ori_win->h_size;
left_win->v_offs = ori_win->v_offs;
left_win->v_size = ori_win->v_size;
right_win->h_offs = ori_win->h_offs - right_isp_rect_.x;
right_win->h_size = ori_win->h_size;
right_win->v_offs = ori_win->v_offs;
right_win->v_size = ori_win->v_size;
}
else {
if ((ori_win->h_offs + ori_win->h_size / 2) <= left_isp_rect_.w
&& right_isp_rect_.x <= (ori_win->h_offs + ori_win->h_size / 2)) {
#ifdef DEBUG
printf(" win locate at left&right isp,and center line locate in overlapping zone!\n");
#endif
*mode = LEFT_AND_RIGHT_MODE;
//win center locate at overlap zone
left_win->h_offs = ori_win->h_offs;
left_win->v_offs = ori_win->v_offs;
left_win->v_size = ori_win->v_size;
right_win->v_offs = ori_win->v_offs;
right_win->v_size = ori_win->v_size;
u16 block_h = ori_win->h_size / (2 * wnd_num);
SplitAecCalcBlockSize(left_win, right_win, wnd_num, right_isp_rect_, &block_h);
}
else {
#ifdef DEBUG
printf(" win locate at left&right isp,but center line not locate in overlapping zone!\n");
#endif
if ((ori_win->h_offs + ori_win->h_size / 2) < right_isp_rect_.x) {
left_win->h_offs = ori_win->h_offs;
left_win->v_offs = ori_win->v_offs;
left_win->v_size = ori_win->v_size;
right_win->v_offs = ori_win->v_offs;
right_win->v_size = ori_win->v_size;
u16 h_size_tmp1 = left_isp_rect_.w - ori_win->h_offs;
u16 h_size_tmp2 = (right_isp_rect_.x - ori_win->h_offs) * 2;
if (abs(ori_win->h_size - h_size_tmp1) < abs(ori_win->h_size - h_size_tmp2)) {
#ifdef DEBUG
printf("correct glb.h_size %d to %d\n", ori_win->h_size, h_size_tmp1);
#endif
*mode = LEFT_MODE;
ori_win->h_size = h_size_tmp1;
left_win->h_size = ori_win->h_size;
//actually stats of right isp would not be used
right_win->h_offs = 0;
right_win->h_size = ori_win->h_size;
}
else {
#ifdef DEBUG
printf("correct glb.h_size %d to %d\n", ori_win->h_size, h_size_tmp2);
#endif
*mode = LEFT_AND_RIGHT_MODE;
ori_win->h_size = h_size_tmp2;
u16 block_h = ori_win->h_size / (2 * wnd_num);
SplitAecCalcBlockSize(left_win, right_win, wnd_num, right_isp_rect_, &block_h);
}
}
else {
left_win->v_offs = ori_win->v_offs;
left_win->v_size = ori_win->v_size;
right_win->v_offs = ori_win->v_offs;
right_win->v_size = ori_win->v_size;
u16 h_size_tmp1 = ori_win->h_offs + ori_win->h_size - right_isp_rect_.x;
u16 h_size_tmp2 = (ori_win->h_offs + ori_win->h_size - left_isp_rect_.w) * 2;
if (abs(ori_win->h_size - h_size_tmp1) < abs(ori_win->h_size - h_size_tmp2)) {
#ifdef DEBUG
printf("correct glb.h_off %d to %d\n", ori_win->h_offs, right_isp_rect_.x);
printf("correct glb.h_size %d to %d\n", ori_win->h_size, h_size_tmp1);
#endif
*mode = RIGHT_MODE;
ori_win->h_size = h_size_tmp1;
ori_win->h_offs = right_isp_rect_.x;
right_win->h_offs = 0;
right_win->h_size = ori_win->h_size;
//actually stats of left isp would not be used
left_win->h_offs = 0;
left_win->h_size = ori_win->h_size;
}
else {
#ifdef DEBUG
printf("correct glb.h_off %d to %d\n", ori_win->h_offs,
ori_win->h_offs + ori_win->h_size - (ori_win->h_offs + ori_win->h_size - left_isp_rect_.w) * 2);
printf("correct glb.h_size %d to %d\n", ori_win->h_size, h_size_tmp2);
#endif
*mode = LEFT_AND_RIGHT_MODE;
ori_win->h_offs = ori_win->h_offs + ori_win->h_size - (ori_win->h_offs + ori_win->h_size - left_isp_rect_.w) * 2;
ori_win->h_size = h_size_tmp2;
left_win->h_offs = ori_win->h_offs;
u16 block_h = ori_win->h_size / (2 * wnd_num);
SplitAecCalcBlockSize(left_win, right_win, wnd_num, right_isp_rect_, &block_h);
}
}
}
}
}
/*********************************************/
/* other module hwi splitter */
/*********************************************/
void SplitAwbCalcBlockSize(
struct isp2x_window* left_win,
struct isp2x_window* right_win,
u8 ds_awb,
u8 wnd_num,
IspParamsSplitter::Rectangle right_isp_rect_,
u16* block_h
) {
bool loop_en = true;
int i = 0;
while (loop_en && *block_h > 0) {
left_win->h_size = (*block_h * wnd_num) << ds_awb;
right_win->h_offs = (left_win->h_size + left_win->h_offs > right_isp_rect_.x) ?
left_win->h_size + left_win->h_offs - right_isp_rect_.x : 0;
if (u32(right_win->h_offs + left_win->h_size) > right_isp_rect_.w ) {
(*block_h)--;
}
else {
loop_en = false;
//if (*block_h % 2)
// (*block_h)--;
left_win->h_size = (*block_h * wnd_num) << ds_awb;
right_win->h_offs = (left_win->h_size + left_win->h_offs > right_isp_rect_.x) ?
left_win->h_size + left_win->h_offs - right_isp_rect_.x : 0;
right_win->h_offs = right_win->h_offs & 0xfffe;
right_win->h_size = (*block_h * wnd_num) << ds_awb;
}
}
}
void SplitAwbWin(
isp2x_window* ori_win,
isp2x_window* left_win,
isp2x_window* right_win,
u8 ds_awb,
u8 wnd_num,
IspParamsSplitter::Rectangle left_isp_rect_,
IspParamsSplitter::Rectangle right_isp_rect_,
WinSplitMode* mode
) {
u16 win_ds_hsize = ori_win->h_size >> ds_awb;
u16 ori_win_hsize_clip = win_ds_hsize << ds_awb;
//win only locate in left isp, actually stats of right isp would not be used
if (ori_win->h_offs + ori_win_hsize_clip <= left_isp_rect_.w) {
LOG1_AWB("win locate in left isp\n");
*mode = LEFT_MODE;
left_win->h_offs = ori_win->h_offs;
left_win->h_size = ori_win_hsize_clip;
left_win->v_offs = ori_win->v_offs;
left_win->v_size = ori_win->v_size;
right_win->h_offs = 0;
right_win->h_size = ori_win_hsize_clip;
right_win->v_offs = ori_win->v_offs;
right_win->v_size = ori_win->v_size;
}
else if (ori_win->h_offs >= right_isp_rect_.x) {
LOG1_AWB("win locate in right isp\n");
*mode = RIGHT_MODE;
//win only locate in right isp, actually stats of left isp would not be used
left_win->h_offs = 0;
left_win->h_size = ori_win->h_size;
left_win->v_offs = ori_win->v_offs;
left_win->v_size = ori_win->v_size;
right_win->h_offs = ori_win->h_offs - right_isp_rect_.x;
right_win->h_size = ori_win->h_size;
right_win->v_offs = ori_win->v_offs;
right_win->v_size = ori_win->v_size;
}
else {
if ((ori_win->h_offs + ori_win->h_size / 2) <= left_isp_rect_.w
&& right_isp_rect_.x <= (ori_win->h_offs + ori_win->h_size / 2)) {
LOG1_AWB(" win locate at left&right isp,and center line locate in overlapping zone!\n");
*mode = LEFT_AND_RIGHT_MODE;
//win center locate at overlap zone
left_win->h_offs = ori_win->h_offs;
left_win->v_offs = ori_win->v_offs;
left_win->v_size = ori_win->v_size;
right_win->v_offs = ori_win->v_offs;
right_win->v_size = ori_win->v_size;
// u16 block_h = ori_win->h_size / (2 * wnd_num);
u16 block_h = win_ds_hsize / (2 * wnd_num);
left_win->h_size = (block_h * wnd_num) << ds_awb;
right_win->h_offs = (left_win->h_size + left_win->h_offs > right_isp_rect_.x) ?
left_win->h_size + left_win->h_offs - right_isp_rect_.x : 0;
right_win->h_offs = right_win->h_offs & 0xfffe;
right_win->h_size = (win_ds_hsize - block_h * wnd_num) << ds_awb;
right_win->h_size = right_win->h_offs + right_win->h_size > right_isp_rect_.w ? (right_isp_rect_.w - right_win->h_offs) : right_win->h_size;
}
else {
LOG1_AWB(" win locate at left&right isp,but center line not locate in overlapping zone!\n");
if ((ori_win->h_offs + ori_win->h_size / 2) < right_isp_rect_.x) {
left_win->h_offs = ori_win->h_offs;
left_win->v_offs = ori_win->v_offs;
left_win->v_size = ori_win->v_size;
right_win->v_offs = ori_win->v_offs;
right_win->v_size = ori_win->v_size;
u16 h_size_tmp1 = left_isp_rect_.w - ori_win->h_offs;
u16 h_size_tmp2 = (right_isp_rect_.x - ori_win->h_offs) * 2;
if (abs(ori_win_hsize_clip - h_size_tmp1) < abs(ori_win_hsize_clip - h_size_tmp2)) {
LOG1_AWB("correct glb.h_size %d to %d\n", ori_win->h_size, h_size_tmp1);
*mode = LEFT_MODE;
ori_win->h_size = h_size_tmp1;
left_win->h_size = ori_win->h_size;
//actually stats of right isp would not be used
right_win->h_offs = 0;
right_win->h_size = ori_win->h_size;
}
else {
LOG1_AWB("correct glb.h_size %d to %d\n", ori_win->h_size, h_size_tmp2);
*mode = LEFT_AND_RIGHT_MODE;
ori_win->h_size = h_size_tmp2;
win_ds_hsize = ori_win->h_size >> ds_awb;
u16 block_h = win_ds_hsize / (2 * wnd_num);
SplitAwbCalcBlockSize(left_win, right_win, ds_awb, wnd_num, right_isp_rect_, &block_h);
}
}
else {
left_win->v_offs = ori_win->v_offs;
left_win->v_size = ori_win->v_size;
right_win->v_offs = ori_win->v_offs;
right_win->v_size = ori_win->v_size;
u16 h_size_tmp1 = ori_win->h_offs + ori_win->h_size - right_isp_rect_.x;
u16 h_size_tmp2 = (ori_win->h_offs + ori_win->h_size - left_isp_rect_.w) * 2;
if (abs(ori_win_hsize_clip - h_size_tmp1) < abs(ori_win_hsize_clip - h_size_tmp2)) {
LOG1_AWB("correct glb.h_off %d to %d\n", ori_win->h_offs, right_isp_rect_.x);
LOG1_AWB("correct glb.h_size %d to %d\n", ori_win->h_size, h_size_tmp1);
*mode = RIGHT_MODE;
ori_win->h_size = h_size_tmp1;
ori_win->h_offs = right_isp_rect_.x;
right_win->h_offs = 0;
right_win->h_size = ori_win->h_size;
//actually stats of left isp would not be used
left_win->h_offs = 0;
left_win->h_size = ori_win->h_size;
}
else {
LOG1_AWB("correct glb.h_off %d to %d\n", ori_win->h_offs,
ori_win->h_offs + ori_win->h_size - (ori_win->h_offs + ori_win->h_size - left_isp_rect_.w) * 2);
LOG1_AWB("correct glb.h_size %d to %d\n", ori_win->h_size, h_size_tmp2);
*mode = LEFT_AND_RIGHT_MODE;
ori_win->h_offs = ori_win->h_offs + ori_win->h_size - (ori_win->h_offs + ori_win->h_size - left_isp_rect_.w) * 2;
ori_win->h_size = h_size_tmp2;
left_win->h_offs = ori_win->h_offs;
win_ds_hsize = ori_win->h_size >> ds_awb;
u16 block_h = win_ds_hsize / (2 * wnd_num);
SplitAwbCalcBlockSize(left_win, right_win, ds_awb, wnd_num, right_isp_rect_, &block_h);
}
}
}
}
}
void SplitAwbMultiWin(
struct isp2x_window* ori_win,
struct isp2x_window* left_win,
struct isp2x_window* right_win,
struct isp2x_window* main_left_win,
struct isp2x_window* main_right_win,
IspParamsSplitter::Rectangle left_isp_rect_,
IspParamsSplitter::Rectangle right_isp_rect_,
WinSplitMode* mode
) {
if (ori_win->h_offs + ori_win->h_size <= main_left_win->h_offs + main_left_win->h_size) {
LOG1_AWB("win locate in left isp\n");
*mode = LEFT_MODE;
left_win->h_offs = ori_win->h_offs;
left_win->h_size = ori_win->h_size;
left_win->v_offs = ori_win->v_offs;
left_win->v_size = ori_win->v_size;
right_win->h_offs = 0;
right_win->h_size = 0;
right_win->v_offs = 0;
right_win->v_size = 0;
}
else if (ori_win->h_offs >= right_isp_rect_.x + main_right_win->h_offs) {
LOG1_AWB("win locate in right isp\n");
*mode = RIGHT_MODE;
//win only locate in right isp, actually stats of left isp would not be used
left_win->h_offs = 0;
left_win->h_size = 0;
left_win->v_offs = 0;
left_win->v_size = 0;
right_win->h_offs = MAX((int)main_right_win->h_offs, (int)ori_win->h_offs - (int)right_isp_rect_.x);
right_win->h_size = ori_win->h_size;
right_win->v_offs = ori_win->v_offs;
right_win->v_size = ori_win->v_size;
}
else {
LOG1_AWB(" win locate at left&right isp\n");
*mode = LEFT_AND_RIGHT_MODE;
left_win->h_offs = ori_win->h_offs;
left_win->h_size = MAX(0, ((int)main_left_win->h_offs + (int)main_left_win->h_size - (int)left_win->h_offs));
left_win->v_offs = ori_win->v_offs;
left_win->v_size = ori_win->v_size;
right_win->h_offs = MAX((int)main_right_win->h_offs, (int)left_win->h_offs + (int)left_win->h_size - (int)right_isp_rect_.x);
right_win->h_size = MAX(0, ((int)ori_win->h_size - (int)left_win->h_size));
right_win->v_offs = ori_win->v_offs;
right_win->v_size = ori_win->v_size;
}
}
}
template <>
XCamReturn IspParamsSplitter::SplitRawAeLiteParams<struct isp2x_rawaelite_meas_cfg>(
struct isp2x_rawaelite_meas_cfg* ori, struct isp2x_rawaelite_meas_cfg* left,
struct isp2x_rawaelite_meas_cfg* right) {
u8 wnd_num = 0;
if (ori->wnd_num == 0)
wnd_num = 1;
else
wnd_num = 5;
WinSplitMode mode = LEFT_AND_RIGHT_MODE;
WinSplitMode sub_mode[4] = {LEFT_AND_RIGHT_MODE};
SplitAecWin(&ori->win, &left->win, &right->win, wnd_num, left_isp_rect_, right_isp_rect_, &mode);
#ifdef DEBUG
printf("AeLite left=%d-%d-%d-%d, right=%d-%d-%d-%d\n", left->win.h_offs, left->win.v_offs,
left->win.h_size, left->win.v_size, right->win.h_offs, right->win.v_offs,
right->win.h_size, right->win.v_size);
#endif
return XCAM_RETURN_NO_ERROR;
}
template <>
XCamReturn IspParamsSplitter::SplitRawAeBigParams<struct isp2x_rawaebig_meas_cfg>(
struct isp2x_rawaebig_meas_cfg* ori, struct isp2x_rawaebig_meas_cfg* left,
struct isp2x_rawaebig_meas_cfg* right) {
u8 wnd_num = 0;
if (ori->wnd_num == 0)
wnd_num = 1;
else if (ori->wnd_num == 1)
wnd_num = 5;
else
wnd_num = 15;
WinSplitMode mode = LEFT_AND_RIGHT_MODE;
WinSplitMode sub_mode[4] = {LEFT_AND_RIGHT_MODE};
SplitAecWin(&ori->win, &left->win, &right->win, wnd_num, left_isp_rect_, right_isp_rect_, &mode);
SplitAecSubWin(ori->subwin_en, ori->subwin, left->subwin, right->subwin, left_isp_rect_, right_isp_rect_, sub_mode);
for (int i = 0; i < ISP2X_RAWAEBIG_SUBWIN_NUM; i++) {
if (ori->subwin_en[i]) {
switch (sub_mode[i]) {
case LEFT_AND_RIGHT_MODE:
left->subwin_en[i] = true;
right->subwin_en[i] = true;
break;
case LEFT_MODE:
left->subwin_en[i] = true;
right->subwin_en[i] = false;
break;
case RIGHT_MODE:
left->subwin_en[i] = false;
right->subwin_en[i] = true;
break;
}
}
}
#ifdef DEBUG
printf("AeBig left=%d-%d-%d-%d, right=%d-%d-%d-%d\n", left->win.h_offs, left->win.v_offs,
left->win.h_size, left->win.v_size, right->win.h_offs, right->win.v_offs,
right->win.h_size, right->win.v_size);
#endif
return XCAM_RETURN_NO_ERROR;
}
template <>
XCamReturn IspParamsSplitter::SplitRawHistLiteParams<struct isp2x_rawhistlite_cfg>(
struct isp2x_rawhistlite_cfg* ori, struct isp2x_rawhistlite_cfg* left,
struct isp2x_rawhistlite_cfg* right) {
u8 wnd_num = 0;
wnd_num = 5;
WinSplitMode mode = LEFT_AND_RIGHT_MODE;
SplitAecWin(&ori->win, &left->win, &right->win, wnd_num, left_isp_rect_, right_isp_rect_, &mode);
SplitAecWeight(ori->weight, left->weight, right->weight, mode, wnd_num);
#ifdef DEBUG
printf("HistLite left=%d-%d-%d-%d, right=%d-%d-%d-%d\n", left->win.h_offs, left->win.v_offs,
left->win.h_size, left->win.v_size, right->win.h_offs, right->win.v_offs,
right->win.h_size, right->win.v_size);
for (int i = 0; i < wnd_num; i++) {
for (int j = 0; j < wnd_num; j++)
printf("%d ", left->weight[i * wnd_num + j]);
printf("\n");
}
for (int i = 0; i < wnd_num; i++) {
for (int j = 0; j < wnd_num; j++)
printf("%d ", right->weight[i * wnd_num + j]);
printf("\n");
}
#endif
return XCAM_RETURN_NO_ERROR;
}
template <>
XCamReturn IspParamsSplitter::SplitRawHistBigParams<struct isp2x_rawhistbig_cfg>(
struct isp2x_rawhistbig_cfg* ori, struct isp2x_rawhistbig_cfg* left,
struct isp2x_rawhistbig_cfg* right) {
u8 wnd_num = 0;
if (ori->wnd_num <= 1)
wnd_num = 5;
else
wnd_num = 15;
WinSplitMode mode = LEFT_AND_RIGHT_MODE;
SplitAecWin(&ori->win, &left->win, &right->win, wnd_num, left_isp_rect_, right_isp_rect_, &mode);
SplitAecWeight(ori->weight, left->weight, right->weight, mode, wnd_num);
#ifdef DEBUG
printf("HistBig left=%d-%d-%d-%d, right=%d-%d-%d-%d\n", left->win.h_offs, left->win.v_offs,
left->win.h_size, left->win.v_size, right->win.h_offs, right->win.v_offs,
right->win.h_size, right->win.v_size);
for (int i = 0; i < wnd_num; i++) {
for (int j = 0; j < wnd_num; j++)
printf("%d ", left->weight[i * wnd_num + j]);
printf("\n");
}
for (int i = 0; i < wnd_num; i++) {
for (int j = 0; j < wnd_num; j++)
printf("%d ", right->weight[i * wnd_num + j]);
printf("\n");
}
#endif
return XCAM_RETURN_NO_ERROR;
}
template <>
XCamReturn IspParamsSplitter::SplitAecParams<struct isp3x_isp_params_cfg>(
struct isp3x_isp_params_cfg* ori,
struct isp3x_isp_params_cfg* left,
struct isp3x_isp_params_cfg* right) {
XCamReturn ret = XCAM_RETURN_NO_ERROR;
//RAWAE
ret = SplitRawAeLiteParams(&ori->meas.rawae0, &left->meas.rawae0, &right->meas.rawae0);
ret = SplitRawAeBigParams(&ori->meas.rawae1, &left->meas.rawae1, &right->meas.rawae1);
ret = SplitRawAeBigParams(&ori->meas.rawae2, &left->meas.rawae2, &right->meas.rawae2);
ret = SplitRawAeBigParams(&ori->meas.rawae3, &left->meas.rawae3, &right->meas.rawae3);
//RAWHIST
ret = SplitRawHistLiteParams(&ori->meas.rawhist0, &left->meas.rawhist0, &right->meas.rawhist0);
ret = SplitRawHistBigParams(&ori->meas.rawhist1, &left->meas.rawhist1, &right->meas.rawhist1);
ret = SplitRawHistBigParams(&ori->meas.rawhist2, &left->meas.rawhist2, &right->meas.rawhist2);
ret = SplitRawHistBigParams(&ori->meas.rawhist3, &left->meas.rawhist3, &right->meas.rawhist3);
return XCAM_RETURN_NO_ERROR;
}
// split Awb param
template <>
XCamReturn IspParamsSplitter::SplitAwbParams<struct isp3x_isp_params_cfg>(
struct isp3x_isp_params_cfg* ori,
struct isp3x_isp_params_cfg* left,
struct isp3x_isp_params_cfg* right) {
XCamReturn ret = XCAM_RETURN_NO_ERROR;
isp2x_window ori_win;
isp2x_window left_win;
isp2x_window right_win;
WinSplitMode mode = LEFT_AND_RIGHT_MODE;
u8 wnd_num = 15;
ori_win.h_offs = ori->meas.rawawb.sw_rawawb_h_offs;
ori_win.h_size = ori->meas.rawawb.sw_rawawb_h_size;
ori_win.v_offs = ori->meas.rawawb.sw_rawawb_v_offs;
ori_win.v_size = ori->meas.rawawb.sw_rawawb_v_size;
memcpy(&left_win, &ori_win, sizeof(ori_win));
memcpy(&right_win, &ori_win, sizeof(ori_win));
// Awb measure window
u8 awb_ds;
if (ori->meas.rawawb.sw_rawawb_wind_size == 0) {
awb_ds = 2;
} else {
awb_ds = 3;
}
u16 min_hsize = wnd_num << awb_ds;
SplitAwbWin(&ori_win, &left_win, &right_win, awb_ds, wnd_num, left_isp_rect_, right_isp_rect_, &mode);
if (ori_win.h_size < min_hsize) {
ori->meas.rawawb.sw_rawawb_blk_measure_enable = 0;
left->meas.rawawb.sw_rawawb_blk_measure_enable = 0;
right->meas.rawawb.sw_rawawb_blk_measure_enable = 0;
}
else {
if (mode == LEFT_AND_RIGHT_MODE) {
if (left_win.h_size < min_hsize)
left->meas.rawawb.sw_rawawb_blk_measure_enable = 0;
if (right_win.h_size < min_hsize)
right->meas.rawawb.sw_rawawb_blk_measure_enable = 0;
}
}
// Awb blk_wei_w
//SplitAwbWeight(&ori_win, &left_win, &right_win, ori->meas.rawawb.sw_rawawb_wp_blk_wei_w, left->meas.rawawb.sw_rawawb_wp_blk_wei_w, right->meas.rawawb.sw_rawawb_wp_blk_wei_w, mode, wnd_num);
SplitAecWeight(ori->meas.rawawb.sw_rawawb_wp_blk_wei_w, left->meas.rawawb.sw_rawawb_wp_blk_wei_w, right->meas.rawawb.sw_rawawb_wp_blk_wei_w, mode, wnd_num);
left->meas.rawawb.sw_rawawb_h_offs = left_win.h_offs;
left->meas.rawawb.sw_rawawb_h_size = left_win.h_size;
left->meas.rawawb.sw_rawawb_v_offs = left_win.v_offs;
left->meas.rawawb.sw_rawawb_v_size = left_win.v_size;
right->meas.rawawb.sw_rawawb_h_offs = right_win.h_offs;
right->meas.rawawb.sw_rawawb_h_size = right_win.h_size;
right->meas.rawawb.sw_rawawb_v_offs = right_win.v_offs;
right->meas.rawawb.sw_rawawb_v_size = right_win.v_size;
LOGD_AWB("Awb measure window left=%d-%d-%d-%d, right=%d-%d-%d-%d\n", left_win.h_offs, left_win.v_offs,
left_win.h_size, left_win.v_size, right_win.h_offs, right_win.v_offs,
right_win.h_size, right_win.v_size);
LOGV_AWB("Awb block weight: \n LEFT = { \n");
for (int i = 0; i < wnd_num; i++) {
for (int j = 0; j < wnd_num; j++)
LOGV_AWB("%d ", left->meas.rawawb.sw_rawawb_wp_blk_wei_w[i * wnd_num + j]);
LOGV_AWB("\n");
}
LOGV_AWB("} \n RIGHT = { \n");
for (int i = 0; i < wnd_num; i++) {
for (int j = 0; j < wnd_num; j++)
LOGV_AWB("%d ", right->meas.rawawb.sw_rawawb_wp_blk_wei_w[i * wnd_num + j]);
LOGV_AWB("\n");
}
LOGV_AWB("} \n");
// Awb Multi Window
isp2x_window sub_ori_win;
isp2x_window sub_left_win;
isp2x_window sub_right_win;
u16 sub_win_st = 0;
u16 sub_win_ed = 0;
u16 main_win_st = 0;
u16 main_win_ed = 0;
if (ori->meas.rawawb.sw_rawawb_multiwindow_en) {
// Awb Multi window 0
sub_ori_win.h_offs = ori->meas.rawawb.sw_rawawb_multiwindow0_h_offs;
sub_ori_win.h_size = ori->meas.rawawb.sw_rawawb_multiwindow0_h_size-ori->meas.rawawb.sw_rawawb_multiwindow0_h_offs;
sub_ori_win.v_offs = ori->meas.rawawb.sw_rawawb_multiwindow0_v_offs;
sub_ori_win.v_size = ori->meas.rawawb.sw_rawawb_multiwindow0_v_size-ori->meas.rawawb.sw_rawawb_multiwindow0_v_offs;
sub_win_st = left_isp_rect_.x + sub_ori_win.h_offs;
sub_win_ed = sub_win_st + sub_ori_win.h_size;
main_win_st = left_isp_rect_.x + ori_win.h_offs;
main_win_ed = main_win_st + ori_win.h_size;
if ((sub_win_ed <= main_win_st) || (sub_win_st >= main_win_ed)) {
LOGW_AWB("multiwindow_0 [hoffs(%d) hsize(%d)] reset to [0 0] \n", sub_ori_win.h_offs, sub_ori_win.h_size);
sub_ori_win.h_offs = 0;
sub_ori_win.h_size = 0;
} else if ((sub_win_st < main_win_st) && (sub_win_ed <= main_win_ed)) {
LOGW_AWB("multiwindow_0 hoffs(%d) reset as same as main window offs(%d) \n", sub_ori_win.h_offs, ori_win.h_offs);
sub_ori_win.h_offs = left_isp_rect_.x + ori_win.h_offs;
} else if ((sub_win_st < main_win_st) && (sub_win_ed > main_win_ed)) {
LOGW_AWB("multiwindow_0 [hoffs(%d) hsize(%d)] reset as same as main window [%d %d] \n", sub_ori_win.h_offs, sub_ori_win.h_size, ori_win.h_offs, ori_win.h_size);
sub_ori_win.h_offs = ori_win.h_offs;
sub_ori_win.h_size = ori_win.h_size;
} else if ((sub_win_st >= main_win_st) && (sub_win_ed > main_win_ed)) {
LOGW_AWB("multiwindow_0 hsize(%d) reset to %d (main_win_ed %d - sub_win_st %d) \n", sub_ori_win.h_size, main_win_ed-sub_win_st, main_win_ed, sub_win_st);
sub_ori_win.h_size = main_win_ed-sub_win_st;
}
memcpy(&sub_left_win, &sub_ori_win, sizeof(sub_ori_win));
memcpy(&sub_right_win, &sub_ori_win, sizeof(sub_ori_win));
SplitAwbMultiWin(&sub_ori_win, &sub_left_win, &sub_right_win, &left_win, &right_win, left_isp_rect_, right_isp_rect_, &mode);
left->meas.rawawb.sw_rawawb_multiwindow0_h_offs = sub_left_win.h_offs;
left->meas.rawawb.sw_rawawb_multiwindow0_h_size = sub_left_win.h_size + sub_left_win.h_offs;
left->meas.rawawb.sw_rawawb_multiwindow0_v_offs = sub_left_win.v_offs;
left->meas.rawawb.sw_rawawb_multiwindow0_v_size = sub_left_win.v_size + sub_left_win.v_offs;
right->meas.rawawb.sw_rawawb_multiwindow0_h_offs = sub_right_win.h_offs;
right->meas.rawawb.sw_rawawb_multiwindow0_h_size = sub_right_win.h_size + sub_right_win.h_offs;
right->meas.rawawb.sw_rawawb_multiwindow0_v_offs = sub_right_win.v_offs;
right->meas.rawawb.sw_rawawb_multiwindow0_v_size = sub_right_win.v_size + sub_right_win.v_offs;
LOGD_AWB("Awb Multi window 0 left=%d-%d-%d-%d, right=%d-%d-%d-%d\n", sub_left_win.h_offs, sub_left_win.v_offs,
sub_left_win.h_size, sub_left_win.v_size, sub_right_win.h_offs, sub_right_win.v_offs,
sub_right_win.h_size, sub_right_win.v_size);
// Awb Multi window 1
sub_ori_win.h_offs = ori->meas.rawawb.sw_rawawb_multiwindow1_h_offs;
sub_ori_win.h_size = ori->meas.rawawb.sw_rawawb_multiwindow1_h_size - ori->meas.rawawb.sw_rawawb_multiwindow1_h_offs;
sub_ori_win.v_offs = ori->meas.rawawb.sw_rawawb_multiwindow1_v_offs;
sub_ori_win.v_size = ori->meas.rawawb.sw_rawawb_multiwindow1_v_size - ori->meas.rawawb.sw_rawawb_multiwindow1_v_offs;
sub_win_st = left_isp_rect_.x + sub_ori_win.h_offs;
sub_win_ed = sub_win_st + sub_ori_win.h_size;
main_win_st = left_isp_rect_.x + ori_win.h_offs;
main_win_ed = main_win_st + ori_win.h_size;
if ((sub_win_ed <= main_win_st) || (sub_win_st >= main_win_ed)) {
LOGW_AWB("multiwindow_1 [hoffs(%d) hsize(%d)] reset to [0 0] \n", sub_ori_win.h_offs, sub_ori_win.h_size);
sub_ori_win.h_offs = 0;
sub_ori_win.h_size = 0;
} else if ((sub_win_st < main_win_st) && (sub_win_ed <= main_win_ed)) {
LOGW_AWB("multiwindow_1 hoffs(%d) reset as same as main window offs(%d) \n", sub_ori_win.h_offs, ori_win.h_offs);
sub_ori_win.h_offs = left_isp_rect_.x + ori_win.h_offs;
} else if ((sub_win_st < main_win_st) && (sub_win_ed > main_win_ed)) {
LOGW_AWB("multiwindow_1 [hoffs(%d) hsize(%d)] reset as same as main window [%d %d] \n", sub_ori_win.h_offs, sub_ori_win.h_size, ori_win.h_offs, ori_win.h_size);
sub_ori_win.h_offs = ori_win.h_offs;
sub_ori_win.h_size = ori_win.h_size;
} else if ((sub_win_st >= main_win_st) && (sub_win_ed > main_win_ed)) {
LOGW_AWB("multiwindow_1 hsize(%d) reset to %d (main_win_ed %d - sub_win_st %d) \n", sub_ori_win.h_size, main_win_ed-sub_win_st, main_win_ed, sub_win_st);
sub_ori_win.h_size = main_win_ed-sub_win_st;
}
memcpy(&sub_left_win, &sub_ori_win, sizeof(sub_ori_win));
memcpy(&sub_right_win, &sub_ori_win, sizeof(sub_ori_win));
SplitAwbMultiWin(&sub_ori_win, &sub_left_win, &sub_right_win, &left_win, &right_win, left_isp_rect_, right_isp_rect_, &mode);
left->meas.rawawb.sw_rawawb_multiwindow1_h_offs = sub_left_win.h_offs;
left->meas.rawawb.sw_rawawb_multiwindow1_h_size = sub_left_win.h_size + sub_left_win.h_offs;
left->meas.rawawb.sw_rawawb_multiwindow1_v_offs = sub_left_win.v_offs;
left->meas.rawawb.sw_rawawb_multiwindow1_v_size = sub_left_win.v_size + sub_left_win.v_offs;
right->meas.rawawb.sw_rawawb_multiwindow1_h_offs = sub_right_win.h_offs;
right->meas.rawawb.sw_rawawb_multiwindow1_h_size = sub_right_win.h_size + sub_right_win.h_offs;
right->meas.rawawb.sw_rawawb_multiwindow1_v_offs = sub_right_win.v_offs;
right->meas.rawawb.sw_rawawb_multiwindow1_v_size = sub_right_win.v_size + sub_right_win.v_offs;
LOGD_AWB("Awb Multi window 1 left=%d-%d-%d-%d, right=%d-%d-%d-%d\n", sub_left_win.h_offs, sub_left_win.v_offs,
sub_left_win.h_size, sub_left_win.v_size, sub_right_win.h_offs, sub_right_win.v_offs,
sub_right_win.h_size, sub_right_win.v_size);
// Awb Multi window 2
sub_ori_win.h_offs = ori->meas.rawawb.sw_rawawb_multiwindow2_h_offs;
sub_ori_win.h_size = ori->meas.rawawb.sw_rawawb_multiwindow2_h_size - ori->meas.rawawb.sw_rawawb_multiwindow2_h_offs;
sub_ori_win.v_offs = ori->meas.rawawb.sw_rawawb_multiwindow2_v_offs;
sub_ori_win.v_size = ori->meas.rawawb.sw_rawawb_multiwindow2_v_size - ori->meas.rawawb.sw_rawawb_multiwindow2_v_offs;
sub_win_st = left_isp_rect_.x + sub_ori_win.h_offs;
sub_win_ed = sub_win_st + sub_ori_win.h_size;
main_win_st = left_isp_rect_.x + ori_win.h_offs;
main_win_ed = main_win_st + ori_win.h_size;
if ((sub_win_ed <= main_win_st) || (sub_win_st >= main_win_ed)) {
LOGW_AWB("multiwindow_2 [hoffs(%d) hsize(%d)] reset to [0 0] \n", sub_ori_win.h_offs, sub_ori_win.h_size);
sub_ori_win.h_offs = 0;
sub_ori_win.h_size = 0;
} else if ((sub_win_st < main_win_st) && (sub_win_ed <= main_win_ed)) {
LOGW_AWB("multiwindow_2 hoffs(%d) reset as same as main window offs(%d) \n", sub_ori_win.h_offs, ori_win.h_offs);
sub_ori_win.h_offs = left_isp_rect_.x + ori_win.h_offs;
} else if ((sub_win_st < main_win_st) && (sub_win_ed > main_win_ed)) {
LOGW_AWB("multiwindow_2 [hoffs(%d) hsize(%d)] reset as same as main window [%d %d] \n", sub_ori_win.h_offs, sub_ori_win.h_size, ori_win.h_offs, ori_win.h_size);
sub_ori_win.h_offs = ori_win.h_offs;
sub_ori_win.h_size = ori_win.h_size;
} else if ((sub_win_st >= main_win_st) && (sub_win_ed > main_win_ed)) {
LOGW_AWB("multiwindow_2 hsize(%d) reset to %d (main_win_ed %d - sub_win_st %d) \n", sub_ori_win.h_size, main_win_ed-sub_win_st, main_win_ed, sub_win_st);
sub_ori_win.h_size = main_win_ed-sub_win_st;
}
memcpy(&sub_left_win, &sub_ori_win, sizeof(sub_ori_win));
memcpy(&sub_right_win, &sub_ori_win, sizeof(sub_ori_win));
SplitAwbMultiWin(&sub_ori_win, &sub_left_win, &sub_right_win, &left_win, &right_win, left_isp_rect_, right_isp_rect_, &mode);
left->meas.rawawb.sw_rawawb_multiwindow2_h_offs = sub_left_win.h_offs;
left->meas.rawawb.sw_rawawb_multiwindow2_h_size = sub_left_win.h_size + sub_left_win.h_offs;
left->meas.rawawb.sw_rawawb_multiwindow2_v_offs = sub_left_win.v_offs;
left->meas.rawawb.sw_rawawb_multiwindow2_v_size = sub_left_win.v_size + sub_left_win.v_offs;
right->meas.rawawb.sw_rawawb_multiwindow2_h_offs = sub_right_win.h_offs;
right->meas.rawawb.sw_rawawb_multiwindow2_h_size = sub_right_win.h_size + sub_right_win.h_offs;
right->meas.rawawb.sw_rawawb_multiwindow2_v_offs = sub_right_win.v_offs;
right->meas.rawawb.sw_rawawb_multiwindow2_v_size = sub_right_win.v_size + sub_right_win.v_offs;
LOGD_AWB("Awb Multi window 2 left=%d-%d-%d-%d, right=%d-%d-%d-%d\n", sub_left_win.h_offs, sub_left_win.v_offs,
sub_left_win.h_size, sub_left_win.v_size, sub_right_win.h_offs, sub_right_win.v_offs,
sub_right_win.h_size, sub_right_win.v_size);
// Awb Multi window 3
sub_ori_win.h_offs = ori->meas.rawawb.sw_rawawb_multiwindow3_h_offs;
sub_ori_win.h_size = ori->meas.rawawb.sw_rawawb_multiwindow3_h_size - ori->meas.rawawb.sw_rawawb_multiwindow3_h_offs;
sub_ori_win.v_offs = ori->meas.rawawb.sw_rawawb_multiwindow3_v_offs;
sub_ori_win.v_size = ori->meas.rawawb.sw_rawawb_multiwindow3_v_size -ori->meas.rawawb.sw_rawawb_multiwindow3_v_offs ;
sub_win_st = left_isp_rect_.x + sub_ori_win.h_offs;
sub_win_ed = sub_win_st + sub_ori_win.h_size;
main_win_st = left_isp_rect_.x + ori_win.h_offs;
main_win_ed = main_win_st + ori_win.h_size;
if ((sub_win_ed <= main_win_st) || (sub_win_st >= main_win_ed)) {
LOGW_AWB("multiwindow_3 [hoffs(%d) hsize(%d)] reset to [0 0] \n", sub_ori_win.h_offs, sub_ori_win.h_size);
sub_ori_win.h_offs = 0;
sub_ori_win.h_size = 0;
} else if ((sub_win_st < main_win_st) && (sub_win_ed <= main_win_ed)) {
LOGW_AWB("multiwindow_3 hoffs(%d) reset as same as main window offs(%d) \n", sub_ori_win.h_offs, ori_win.h_offs);
sub_ori_win.h_offs = left_isp_rect_.x + ori_win.h_offs;
} else if ((sub_win_st < main_win_st) && (sub_win_ed > main_win_ed)) {
LOGW_AWB("multiwindow_3 [hoffs(%d) hsize(%d)] reset as same as main window [%d %d] \n", sub_ori_win.h_offs, sub_ori_win.h_size, ori_win.h_offs, ori_win.h_size);
sub_ori_win.h_offs = ori_win.h_offs;
sub_ori_win.h_size = ori_win.h_size;
} else if ((sub_win_st >= main_win_st) && (sub_win_ed > main_win_ed)) {
LOGW_AWB("multiwindow_3 hsize(%d) reset to %d (main_win_ed %d - sub_win_st %d) \n", sub_ori_win.h_size, main_win_ed-sub_win_st, main_win_ed, sub_win_st);
sub_ori_win.h_size = main_win_ed-sub_win_st;
}
memcpy(&sub_left_win, &sub_ori_win, sizeof(sub_ori_win));
memcpy(&sub_right_win, &sub_ori_win, sizeof(sub_ori_win));
SplitAwbMultiWin(&sub_ori_win, &sub_left_win, &sub_right_win, &left_win, &right_win, left_isp_rect_, right_isp_rect_, &mode);
left->meas.rawawb.sw_rawawb_multiwindow3_h_offs = sub_left_win.h_offs;
left->meas.rawawb.sw_rawawb_multiwindow3_h_size = sub_left_win.h_size + sub_left_win.h_offs;
left->meas.rawawb.sw_rawawb_multiwindow3_v_offs = sub_left_win.v_offs;
left->meas.rawawb.sw_rawawb_multiwindow3_v_size = sub_left_win.v_size + sub_left_win.v_offs ;
right->meas.rawawb.sw_rawawb_multiwindow3_h_offs = sub_right_win.h_offs;
right->meas.rawawb.sw_rawawb_multiwindow3_h_size = sub_right_win.h_size + sub_right_win.h_offs;
right->meas.rawawb.sw_rawawb_multiwindow3_v_offs = sub_right_win.v_offs;
right->meas.rawawb.sw_rawawb_multiwindow3_v_size = sub_right_win.v_size + sub_right_win.v_offs;
LOGD_AWB("Awb Multi window 3 left=%d-%d-%d-%d, right=%d-%d-%d-%d\n", sub_left_win.h_offs, sub_left_win.v_offs,
sub_left_win.h_size, sub_left_win.v_size, sub_right_win.h_offs, sub_right_win.v_offs,
sub_right_win.h_size, sub_right_win.v_size);
}
return ret;
}
template <>
XCamReturn IspParamsSplitter::SplitAfParams<struct isp3x_isp_params_cfg>(
struct isp3x_isp_params_cfg* ori,
struct isp3x_isp_params_cfg* left,
struct isp3x_isp_params_cfg* right) {
struct isp3x_rawaf_meas_cfg org_af = left->meas.rawaf;
struct isp3x_rawaf_meas_cfg* l_af = &left->meas.rawaf;
struct isp3x_rawaf_meas_cfg* r_af = &right->meas.rawaf;
struct isp2x_rawaebig_meas_cfg org_ae3 = left->meas.rawae3;
struct isp2x_rawaebig_meas_cfg* l_ae3 = &left->meas.rawae3;
struct isp2x_rawaebig_meas_cfg* r_ae3 = &right->meas.rawae3;
int32_t l_isp_st, l_isp_ed, r_isp_st, r_isp_ed;
int32_t l_win_st, l_win_ed, r_win_st, r_win_ed;
int32_t x_st, x_ed, l_blknum, r_blknum, ov_w, blk_w, r_skip_blknum;
ov_w = left_isp_rect_.w + left_isp_rect_.x - right_isp_rect_.x;
x_st = org_af.win[0].h_offs;
x_ed = x_st + org_af.win[0].h_size;
l_isp_st = left_isp_rect_.x;
l_isp_ed = left_isp_rect_.x + left_isp_rect_.w;
r_isp_st = right_isp_rect_.x;
r_isp_ed = right_isp_rect_.x + right_isp_rect_.w;
LOGD_AF("wina.x_st %d, wina.x_ed %d, l_isp_st %d, l_isp_ed %d, r_isp_st %d, r_isp_ed %d",
x_st, x_ed, l_isp_st, l_isp_ed, r_isp_st, r_isp_ed);
//// winA ////
// af win in both side
if ((x_st < r_isp_st) && (x_ed > l_isp_ed)) {
// af win < one isp width
if (org_af.win[0].h_size < left_isp_rect_.w) {
blk_w = org_af.win[0].h_size / ISP2X_RAWAF_SUMDATA_ROW;
l_blknum = (l_isp_ed - x_st + blk_w - 1) / blk_w;
r_blknum = ISP2X_RAWAF_SUMDATA_ROW - l_blknum;
l_win_ed = l_isp_ed - 2;
l_win_st = l_win_ed - blk_w * ISP2X_RAWAF_SUMDATA_ROW;
if (blk_w < ov_w) {
r_skip_blknum = ov_w / blk_w;
r_win_st = ov_w - r_skip_blknum * blk_w;
r_win_ed = ov_w + (ISP2X_RAWAF_SUMDATA_ROW - r_skip_blknum) * blk_w;
}
else {
r_skip_blknum = 0;
r_win_st = 2;
r_win_ed = r_win_st + ISP2X_RAWAF_SUMDATA_ROW * blk_w;
}
}
// af win < one isp width * 1.5
else if (org_af.win[0].h_size < left_isp_rect_.w * 3/2) {
l_win_st = x_st;
l_win_ed = l_isp_ed - 2;
blk_w = (l_win_ed - l_win_st) / (ISP2X_RAWAF_SUMDATA_ROW + 1);
l_win_st = l_win_ed - blk_w * ISP2X_RAWAF_SUMDATA_ROW;
l_blknum = ((l_win_ed - l_win_st) * ISP2X_RAWAF_SUMDATA_ROW + org_af.win[0].h_size - 1) / org_af.win[0].h_size;
r_blknum = ISP2X_RAWAF_SUMDATA_ROW - l_blknum;
if (blk_w < ov_w) {
r_skip_blknum = ov_w / blk_w;
r_win_st = ov_w - r_skip_blknum * blk_w;
r_win_ed = ov_w + (ISP2X_RAWAF_SUMDATA_ROW - r_skip_blknum) * blk_w;
}
else {
r_skip_blknum = 0;
r_win_st = 2;
r_win_ed = r_win_st + ISP2X_RAWAF_SUMDATA_ROW * blk_w;
}
} else {
l_win_st = x_st;
l_win_ed = l_isp_ed - 2;
blk_w = (l_win_ed - l_win_st) / ISP2X_RAWAF_SUMDATA_ROW;
l_win_st = l_win_ed - blk_w * ISP2X_RAWAF_SUMDATA_ROW;
r_win_st = 2;
r_win_ed = r_win_st + blk_w * ISP2X_RAWAF_SUMDATA_ROW;
l_blknum = ISP2X_RAWAF_SUMDATA_ROW;
r_blknum = ISP2X_RAWAF_SUMDATA_ROW;
r_skip_blknum = 0;
}
LOGD_AF("wina: blk_w %d, ov_w %d, l_blknum %d, r_blknum %d, r_skip_blknum %d",
blk_w, ov_w, l_blknum, r_blknum, r_skip_blknum);
}
// af win in right side
else if ((x_st >= r_isp_st) && (x_ed > l_isp_ed)) {
l_blknum = 0;
r_blknum = ISP2X_RAWAF_SUMDATA_ROW;
r_win_st = x_st - right_isp_rect_.x;
r_win_ed = x_ed - right_isp_rect_.x;
l_win_st = r_win_st;
l_win_ed = r_win_ed;
}
// af win in left side
else {
l_blknum = ISP2X_RAWAF_SUMDATA_ROW;
r_blknum = 0;
l_win_st = x_st;
l_win_ed = x_ed;
r_win_st = l_win_st;
r_win_ed = l_win_ed;
}
l_af->win[0].h_offs = l_win_st;
l_af->win[0].h_size = l_win_ed - l_win_st;
r_af->win[0].h_offs = r_win_st;
r_af->win[0].h_size = r_win_ed - r_win_st;
//// winB ////
x_st = org_af.win[1].h_offs;
x_ed = x_st + org_af.win[1].h_size;
LOGD_AF("winb.x_st %d, winb.x_ed %d, l_isp_st %d, l_isp_ed %d, r_isp_st %d, r_isp_ed %d",
x_st, x_ed, l_isp_st, l_isp_ed, r_isp_st, r_isp_ed);
// af win in both side
if ((x_st < r_isp_st) && (x_ed > l_isp_ed)) {
l_win_st = x_st;
l_win_ed = l_isp_ed - 2;
r_win_st = ov_w - 2;
r_win_ed = x_ed - right_isp_rect_.x;
}
// af win in right side
else if ((x_st >= r_isp_st) && (x_ed > l_isp_ed)) {
r_win_st = x_st - right_isp_rect_.x;
r_win_ed = x_ed - right_isp_rect_.x;
l_win_st = r_win_st;
l_win_ed = r_win_ed;
}
// af win in left side
else {
l_win_st = x_st;
l_win_ed = x_ed;
r_win_st = l_win_st;
r_win_ed = l_win_ed;
}
l_af->win[1].h_offs = l_win_st;
l_af->win[1].h_size = l_win_ed - l_win_st;
r_af->win[1].h_offs = r_win_st;
r_af->win[1].h_size = r_win_ed - r_win_st;
// rawae3 is used by af now!!!
if (org_af.ae_mode) {
l_ae3->win.h_offs = l_af->win[0].h_offs;
l_ae3->win.v_offs = l_af->win[0].v_offs;
l_ae3->win.h_size = l_af->win[0].h_size;
l_ae3->win.v_size = l_af->win[0].v_size;
r_ae3->win.h_offs = r_af->win[0].h_offs;
r_ae3->win.v_offs = r_af->win[0].v_offs;
r_ae3->win.h_size = r_af->win[0].h_size;
r_ae3->win.v_size = r_af->win[0].v_size;
}
LOGD_AF("AfWinA left=%d-%d-%d-%d, right=%d-%d-%d-%d",
l_af->win[0].h_offs, l_af->win[0].v_offs,
l_af->win[0].h_size, l_af->win[0].v_size,
r_af->win[0].h_offs, r_af->win[0].v_offs,
r_af->win[0].h_size, r_af->win[0].v_size);
LOGD_AF("AfWinB left=%d-%d-%d-%d, right=%d-%d-%d-%d",
l_af->win[1].h_offs, l_af->win[1].v_offs,
l_af->win[1].h_size, l_af->win[1].v_size,
r_af->win[1].h_offs, r_af->win[1].v_offs,
r_af->win[1].h_size, r_af->win[1].v_size);
return XCAM_RETURN_NO_ERROR;
}
int AlscMatrixScale(unsigned short ori_matrix[], unsigned short left_matrix[],
unsigned short right_matrix[], int cols, int rows) {
int ori_col_index = 0;
int lef_dst_index = 0;
int rht_dst_index = 0;
int mid_col = cols / 2;
int row_index = 0;
for (row_index = 0; row_index < rows; row_index++) {
for (ori_col_index = 0; ori_col_index < cols;ori_col_index++) {
if (ori_col_index < mid_col) {
left_matrix[lef_dst_index++] =
ori_matrix[row_index * cols + ori_col_index];
left_matrix[lef_dst_index++] =
(ori_matrix[row_index * cols + ori_col_index] +
ori_matrix[row_index * cols + ori_col_index + 1]) / 2;
} else if (ori_col_index == mid_col) {
left_matrix[lef_dst_index++] =
ori_matrix[row_index * cols + ori_col_index];
right_matrix[rht_dst_index++] =
ori_matrix[row_index * cols + ori_col_index];
} else {
right_matrix[rht_dst_index++] =
(ori_matrix[row_index * cols + ori_col_index] +
ori_matrix[row_index * cols + ori_col_index - 1]) / 2;
right_matrix[rht_dst_index++] =
ori_matrix[row_index * cols + ori_col_index];
}
}
}
return 0;
}
int AlscMatrixSplit(const unsigned short* ori_matrix, int cols, int rows, unsigned short left[],
unsigned short right[]) {
int out_cols = cols / 2 + cols % 2;
int out_rows = rows;
int left_start_addr = 0;
int right_start_addr = cols - out_cols;
unsigned short* left_index = left;
unsigned short* right_index = right;
while (out_rows--) {
memcpy(left_index, ori_matrix + left_start_addr, out_cols * sizeof(unsigned short));
memcpy(right_index, ori_matrix + right_start_addr, out_cols * sizeof(unsigned short));
left_index += out_cols;
right_index += out_cols;
left_start_addr += cols;
right_start_addr += cols;
}
return 0;
}
int SplitAlscXtable(const unsigned short* in_array, int in_size, int ori_imgw,
unsigned short* dst_left, unsigned short* dst_right,
int left_w, int right_w) {
int in_index = 0;
int left_index = 0;
int right_index = 0;
for (in_index = 0; in_index < in_size; in_index++) {
if (in_index < (in_size / 2)) {
dst_left[left_index++] =
ceil(in_array[in_index] * 1.0 / ori_imgw * left_w);
dst_left[left_index++] =
floor(in_array[in_index] * 1.0 / ori_imgw * left_w);
} else {
dst_right[right_index++] =
ceil(in_array[in_index] * 1.0 / ori_imgw * right_w);
dst_right[right_index++] =
floor(in_array[in_index] * 1.0 / ori_imgw * right_w);
}
}
return 0;
}
int lscGradUpdate(unsigned short xgrad_tbl[],
unsigned short ygrad_tbl[],
unsigned short x_sect_tbl[],
unsigned short y_sect_tbl[],
int x_sect_size,
int y_sect_size) {
uint32_t x_size = x_sect_size;
uint32_t y_size = y_sect_size;
for (uint32_t i = 0; i < x_size; i++) {
if (0 < x_sect_tbl[i]) {
xgrad_tbl[i] = (uint16_t)((double)(1UL << 15) / x_sect_tbl[i] + 0.5);
} else {
return XCAM_RETURN_ERROR_PARAM;
}
}
for (uint32_t i = 0; i < y_size; i++) {
if (0 < y_sect_tbl[i]) {
ygrad_tbl[i] = (uint16_t)((double)(1UL << 15) / y_sect_tbl[i] + 0.5);
} else {
return XCAM_RETURN_ERROR_PARAM;
}
}
return XCAM_RETURN_NO_ERROR;
}
template <>
XCamReturn IspParamsSplitter::SplitAlscParams<struct isp3x_isp_params_cfg>(
struct isp3x_isp_params_cfg* ori, struct isp3x_isp_params_cfg* left,
struct isp3x_isp_params_cfg* right) {
struct isp3x_lsc_cfg* lsc_cfg_ori = &ori->others.lsc_cfg;
struct isp3x_lsc_cfg* lsc_cfg_lef = &left->others.lsc_cfg;
struct isp3x_lsc_cfg* lsc_cfg_rht = &right->others.lsc_cfg;
memcpy(lsc_cfg_lef->y_size_tbl, lsc_cfg_ori->y_size_tbl,
sizeof(lsc_cfg_ori->y_size_tbl));
memcpy(lsc_cfg_rht->y_size_tbl, lsc_cfg_ori->y_size_tbl,
sizeof(lsc_cfg_ori->y_size_tbl));
SplitAlscXtable(lsc_cfg_ori->x_size_tbl, ISP3X_LSC_SIZE_TBL_SIZE,
pic_rect_.w,
lsc_cfg_lef->x_size_tbl,
lsc_cfg_rht->x_size_tbl,
left_isp_rect_.w,
right_isp_rect_.w);
AlscMatrixScale(lsc_cfg_ori->r_data_tbl,
lsc_cfg_lef->r_data_tbl,
lsc_cfg_rht->r_data_tbl,
ISP3X_LSC_SIZE_TBL_SIZE + 1,
ISP3X_LSC_SIZE_TBL_SIZE + 1);
AlscMatrixScale(lsc_cfg_ori->gr_data_tbl,
lsc_cfg_lef->gr_data_tbl,
lsc_cfg_rht->gr_data_tbl,
ISP3X_LSC_SIZE_TBL_SIZE + 1,
ISP3X_LSC_SIZE_TBL_SIZE + 1);
AlscMatrixScale(lsc_cfg_ori->gb_data_tbl,
lsc_cfg_lef->gb_data_tbl,
lsc_cfg_rht->gb_data_tbl,
ISP3X_LSC_SIZE_TBL_SIZE + 1,
ISP3X_LSC_SIZE_TBL_SIZE + 1);
AlscMatrixScale(lsc_cfg_ori->b_data_tbl,
lsc_cfg_lef->b_data_tbl,
lsc_cfg_rht->b_data_tbl,
ISP3X_LSC_SIZE_TBL_SIZE + 1,
ISP3X_LSC_SIZE_TBL_SIZE + 1);
lscGradUpdate(lsc_cfg_lef->x_grad_tbl, lsc_cfg_lef->y_grad_tbl,
lsc_cfg_lef->x_size_tbl, lsc_cfg_lef->y_size_tbl,
ISP3X_LSC_GRAD_TBL_SIZE, ISP3X_LSC_GRAD_TBL_SIZE);
lscGradUpdate(lsc_cfg_rht->x_grad_tbl, lsc_cfg_rht->y_grad_tbl,
lsc_cfg_rht->x_size_tbl, lsc_cfg_rht->y_size_tbl,
ISP3X_LSC_GRAD_TBL_SIZE, ISP3X_LSC_GRAD_TBL_SIZE);
return XCAM_RETURN_NO_ERROR;
}
IspParamsSplitter& IspParamsSplitter::SetPicInfo(IspParamsSplitter::Rectangle&& pic_rect) {
pic_rect_ = std::move(pic_rect);
return *this;
}
IspParamsSplitter& IspParamsSplitter::SetPicInfo(IspParamsSplitter::Rectangle& pic_rect) {
pic_rect_ = pic_rect;
return *this;
}
IspParamsSplitter& IspParamsSplitter::SetLeftIspRect(IspParamsSplitter::Rectangle&& left_isp_rect) {
left_isp_rect_ = std::move(left_isp_rect);
return *this;
}
IspParamsSplitter& IspParamsSplitter::SetLeftIspRect(IspParamsSplitter::Rectangle& left_isp_rect) {
left_isp_rect_ = left_isp_rect;
return *this;
}
IspParamsSplitter& IspParamsSplitter::SetRightIspRect(
IspParamsSplitter::Rectangle&& right_isp_rect) {
right_isp_rect_ = std::move(right_isp_rect);
return *this;
}
IspParamsSplitter& IspParamsSplitter::SetRightIspRect(
IspParamsSplitter::Rectangle& right_isp_rect) {
right_isp_rect_ = right_isp_rect;
return *this;
}
const IspParamsSplitter::Rectangle& IspParamsSplitter::GetPicInfo() const {
return pic_rect_;
}
const IspParamsSplitter::Rectangle& IspParamsSplitter::GetLeftIspRect() const {
return left_isp_rect_;
}
const IspParamsSplitter::Rectangle& IspParamsSplitter::GetRightIspRect() const {
return right_isp_rect_;
}
template <>
XCamReturn IspParamsSplitter::SplitIspParams<struct isp3x_isp_params_cfg>(
struct isp3x_isp_params_cfg* orig_isp_params,
struct isp3x_isp_params_cfg* isp_params) {
XCamReturn ret = XCAM_RETURN_NO_ERROR;
struct isp3x_isp_params_cfg* left_isp_params = isp_params;
struct isp3x_isp_params_cfg* right_isp_params = isp_params + 1;
// Modules that use the same params for both left and right isp
// will not need to implent split function
memcpy(right_isp_params, left_isp_params, sizeof(struct isp3x_isp_params_cfg));
ret = SplitAecParams(orig_isp_params, left_isp_params, right_isp_params);
// Should return failure ?
ret = SplitAwbParams(orig_isp_params, left_isp_params, right_isp_params);
ret = SplitAfParams(orig_isp_params, left_isp_params, right_isp_params);
ret = SplitAlscParams(orig_isp_params, left_isp_params, right_isp_params);
LOGD_CAMHW("Split ISP Params: left %p right %p size %d",
left_isp_params,
right_isp_params,
sizeof(*left_isp_params));
return ret;
}