android13/external/camera_engine_rkaiq/hwi/isp20/CaptureRawData.cpp

937 lines
37 KiB
C++

/*
* Copyright (c) 2021 Rockchip Corporation
*
* 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.
*
*/
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
#include "rk_aiq_comm.h"
#include "CaptureRawData.h"
#ifndef DIV_ROUND_UP
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
#endif
#ifdef ANDROID_OS
#define DEFAULT_CAPTURE_RAW_PATH "/data/capture_image"
#define CAPTURE_CNT_FILENAME "/data/.capture_cnt"
#else
#define DEFAULT_CAPTURE_RAW_PATH "/tmp/capture_image"
#define CAPTURE_CNT_FILENAME "/tmp/.capture_cnt"
#endif
#define WRITE_RAW_FILE_HEADER
/*
* #define WRITE_ISP_REG
* #define WRITE_ISPP_REG
*/
#define ISP_REGS_BASE 0xffb50000
#define ISPP_REGS_BASE 0xffb60000
#define RAW_FILE_IDENT 0x8080
#define HEADER_LEN 128U
/*
* Raw file structure:
*
+------------+-----------------+-------------+-----------------+---------------------------+
| ITEM | PARAMETER | DATA TYPE | LENGTH(Bytes) | DESCRIPTION |
+------------+-----------------+-------------+-----------------+---------------------------+
| | Identifier | uint16_t | 2 | fixed 0x8080 |
| +-----------------+-------------+-----------------+---------------------------+
| | Header length | uint16_t | 2 | fixed 128U |
| +-----------------+-------------+-----------------+---------------------------+
| | Frame index | uint32_t | 4 | |
| +-----------------+-------------+-----------------+---------------------------+
| | Width | uint16_t | 2 | image width |
| +-----------------+-------------+-----------------+---------------------------+
| | Height | uint16_t | 2 | image height |
| +-----------------+-------------+-----------------+---------------------------+
| | Bit depth | uint8_t | 1 | image bit depth |
| +-----------------+-------------+-----------------+---------------------------+
| | | | | 0: BGGR; 1: GBRG; |
| | Bayer format | uint8_t | 1 | 2: GRBG; 3: RGGB; |
| +-----------------+-------------+-----------------+---------------------------+
| | | | | 1: linear |
| FRAME | Number of HDR | | | 2: long + short |
| HEADER | frame | uint8_t | 1 | 3: long + mid + short |
| +-----------------+-------------+-----------------+---------------------------+
| | | | | 1: short |
| | Current frame | | | 2: mid |
| | type | uint8_t | 1 | 3: long |
| +-----------------+-------------+-----------------+---------------------------+
| | Storage type | uint8_t | 1 | 0: packed; 1: unpacked |
| +-----------------+-------------+-----------------+---------------------------+
| | Line stride | uint16_t | 2 | In bytes |
| +-----------------+-------------+-----------------+---------------------------+
| | Effective | | | |
| | line stride | uint16_t | 2 | In bytes |
| +-----------------+-------------+-----------------+---------------------------+
| | Reserved | uint8_t | 107 | |
+------------+-----------------+-------------+-----------------+---------------------------+
| | | | | |
| RAW DATA | RAW DATA | RAW | W * H * bpp | RAW DATA |
| | | | | |
+------------+-----------------+-------------+-----------------+---------------------------+
*/
/*
* the structure of measuure parameters from isp in meta_data file:
*
* "frame%08d-l_m_s-gain[%08.5f_%08.5f_%08.5f]-time[%08.5f_%08.5f_%08.5f]-awbGain[%08.4f_%08.4f_%08.4f_%08.4f]-dgain[%08d]"
*
*/
namespace RkCam {
const struct capture_fmt CaptureRawData::csirx_fmts[] =
{
/* raw */
{
.fourcc = V4L2_PIX_FMT_SRGGB8,
.bayer_fmt = 3,
.pcpp = 1,
.bpp = { 8 },
}, {
.fourcc = V4L2_PIX_FMT_SGRBG8,
.bayer_fmt = 2,
.pcpp = 1,
.bpp = { 8 },
}, {
.fourcc = V4L2_PIX_FMT_SGBRG8,
.bayer_fmt = 1,
.pcpp = 1,
.bpp = { 8 },
}, {
.fourcc = V4L2_PIX_FMT_SBGGR8,
.bayer_fmt = 0,
.pcpp = 1,
.bpp = { 8 },
}, {
.fourcc = V4L2_PIX_FMT_SRGGB10,
.bayer_fmt = 3,
.pcpp = 4,
.bpp = { 10 },
}, {
.fourcc = V4L2_PIX_FMT_SGRBG10,
.bayer_fmt = 2,
.pcpp = 4,
.bpp = { 10 },
}, {
.fourcc = V4L2_PIX_FMT_SGBRG10,
.bayer_fmt = 1,
.pcpp = 4,
.bpp = { 10 },
}, {
.fourcc = V4L2_PIX_FMT_SBGGR10,
.bayer_fmt = 0,
.pcpp = 4,
.bpp = { 10 },
}, {
.fourcc = V4L2_PIX_FMT_SRGGB12,
.bayer_fmt = 3,
.pcpp = 2,
.bpp = { 12 },
}, {
.fourcc = V4L2_PIX_FMT_SGRBG12,
.bayer_fmt = 2,
.pcpp = 2,
.bpp = { 12 },
}, {
.fourcc = V4L2_PIX_FMT_SGBRG12,
.bayer_fmt = 1,
.pcpp = 2,
.bpp = { 12 },
}, {
.fourcc = V4L2_PIX_FMT_SBGGR12,
.bayer_fmt = 0,
.pcpp = 2,
.bpp = { 12 },
},
};
CaptureRawData::CaptureRawData ()
: sns_width(0)
, sns_height(0)
, pixelformat(0)
, _stride_perline(0)
, _is_raw_dir_exist(false)
, _is_capture_raw(false)
, _capture_raw_num(0)
, _capture_metadata_num(0)
, _capture_image_mutex(false)
, _capture_image_cond(false)
, _capture_raw_type(CAPTURE_RAW_ASYNC)
, _camId(-1)
{
}
CaptureRawData::CaptureRawData(int32_t camId)
: sns_width(0)
, sns_height(0)
, pixelformat(0)
, _stride_perline(0)
, _is_raw_dir_exist(false)
, _is_capture_raw(false)
, _capture_raw_num(0)
, _capture_metadata_num(0)
, _capture_image_mutex(false)
, _capture_image_cond(false)
, _capture_raw_type(CAPTURE_RAW_ASYNC)
, _camId(camId)
{
}
CaptureRawData::~CaptureRawData ()
{
}
const struct capture_fmt* CaptureRawData::find_fmt(const uint32_t pixelformat)
{
const struct capture_fmt *fmt;
unsigned int i;
for (i = 0; i < sizeof(csirx_fmts); i++) {
fmt = &csirx_fmts[i];
if (fmt->fourcc == pixelformat)
return fmt;
}
return NULL;
}
bool
CaptureRawData::get_value_from_file(const char* path, int& value, uint32_t& frameId)
{
const char *delim = " ";
char buffer[16] = {0};
int fp;
fp = open(path, O_RDONLY | O_SYNC);
if (fp != -1) {
if (read(fp, buffer, sizeof(buffer)) <= 0) {
LOGV_CAMHW_SUBM(CAPTURERAW_SUBM, "%s read %s failed!\n", __func__, path);
} else {
char *p = nullptr;
p = strtok(buffer, delim);
if (p != nullptr) {
value = atoi(p);
p = strtok(nullptr, delim);
if (p != nullptr)
frameId = atoi(p);
}
}
close(fp);
LOGV_CAMHW_SUBM(CAPTURERAW_SUBM, "value: %d, frameId: %d\n", value, frameId);
return true;
}
return false;
}
bool
CaptureRawData::set_value_to_file(const char* path, int value, uint32_t sequence)
{
char buffer[16] = {0};
int fp;
if (access(path, F_OK) == -1)
return false;
fp = open(path, O_CREAT | O_RDWR | O_SYNC, S_IRWXU | S_IRUSR | S_IXUSR | S_IROTH | S_IXOTH);
if (fp != -1) {
ftruncate(fp, 0);
lseek(fp, 0, SEEK_SET);
snprintf(buffer, sizeof(buffer), "%3d %8u\n", _capture_raw_num, sequence);
if (write(fp, buffer, sizeof(buffer)) <= 0) {
LOGW_CAMHW_SUBM(CAPTURERAW_SUBM, "%s write %s failed!\n", __func__, path);
}
close(fp);
return true;
}
return false;
}
int CaptureRawData::detect_capture_raw_status(uint32_t sequence, bool first_trigger)
{
char file_name[64] = {0};
snprintf(file_name, sizeof(file_name), "%s", CAPTURE_CNT_FILENAME);
if (!_is_capture_raw) {
uint32_t rawFrmId = 0;
bool ret = get_value_from_file(file_name, _capture_raw_num, rawFrmId);
if (!ret) {
// test multi cam mode
snprintf(file_name, sizeof(file_name), "%.50s_c%d", CAPTURE_CNT_FILENAME, _camId);
get_value_from_file(file_name, _capture_raw_num, rawFrmId);
}
if (_capture_raw_num > 0) {
bool ret = set_value_to_file(file_name, _capture_raw_num, sequence);
if (!ret) {
// test multi cam mode
snprintf(file_name, sizeof(file_name), "%.50s_c%d", CAPTURE_CNT_FILENAME, _camId);
set_value_to_file(file_name, _capture_raw_num, sequence);
}
_is_capture_raw = true;
_capture_metadata_num = _capture_raw_num;
if (first_trigger)
++_capture_metadata_num;
}
}
return 0;
}
int CaptureRawData::update_capture_raw_status(bool first_trigger)
{
char file_name[64] = {0};
snprintf(file_name, sizeof(file_name), "%.63s", CAPTURE_CNT_FILENAME);
if (_is_capture_raw && !first_trigger) {
if (_capture_raw_type == CAPTURE_RAW_AND_YUV_SYNC) {
_capture_image_mutex.lock();
_capture_image_cond.timedwait(_capture_image_mutex, 3000000);
_capture_image_mutex.unlock();
}
if (!--_capture_raw_num) {
bool ret = set_value_to_file(file_name, _capture_raw_num);
if (!ret) {
// test multi cam mode
snprintf(file_name, sizeof(file_name), "%.50s_c%d", CAPTURE_CNT_FILENAME, _camId);
set_value_to_file(file_name, _capture_raw_num);
}
_is_capture_raw = false;
}
}
return 0;
}
int CaptureRawData::dynamic_capture_raw
(
int i,
uint32_t sequence,
SmartPtr<V4l2BufferProxy> buf_proxy,
SmartPtr<V4l2Buffer> &v4l2buf,
int mipi_dev_max,
int working_mode,
SmartPtr<V4l2Device> dev
)
{
if (_is_capture_raw && _capture_raw_num > 0) {
if (!_is_raw_dir_exist) {
if (_capture_raw_type == CAPTURE_RAW_SYNC)
creat_raw_dir(user_set_raw_dir);
else
creat_raw_dir(DEFAULT_CAPTURE_RAW_PATH);
}
if (_is_raw_dir_exist) {
char raw_name[128] = {0};
FILE *fp = nullptr;
sns_width = v4l2buf->get_format().fmt.pix.width;
sns_height = v4l2buf->get_format().fmt.pix.height;
pixelformat = v4l2buf->get_format().fmt.pix.pixelformat;
XCAM_STATIC_PROFILING_START(write_raw);
memset(raw_name, 0, sizeof(raw_name));
if (mipi_dev_max == 1)
snprintf(raw_name, sizeof(raw_name),
"%s/frame%u_%ux%u_%s.raw",
raw_dir_path,
sequence,
sns_width,
sns_height,
"normal");
else if (mipi_dev_max == 2)
snprintf(raw_name, sizeof(raw_name),
"%s/frame%u_%ux%u_%s.raw",
raw_dir_path,
sequence,
sns_width,
sns_height,
i == 0 ? "short" : "long");
else
snprintf(raw_name, sizeof(raw_name),
"%s/frame%u_%ux%u_%s.raw",
raw_dir_path,
sequence,
sns_width,
sns_height,
i == 0 ? "short" : i == 1 ? "middle" : "long");
fp = fopen(raw_name, "wb+");
if (fp != nullptr) {
int size = 0;
#ifdef WRITE_RAW_FILE_HEADER
write_frame_header_to_raw(fp, i, sequence, working_mode, dev);
#endif
#if 0
size = v4l2buf->get_buf().m.planes[0].length;
#else
/* raw image size compatible with ISP expansion line mode */
size = _stride_perline * sns_height;
#endif
write_raw_to_file(fp, i, sequence,
(void *)(buf_proxy->get_v4l2_userptr()),
size);
fclose(fp);
}
XCAM_STATIC_PROFILING_END(write_raw, 0);
}
}
return 0;
}
void
CaptureRawData::write_metadata_to_file(const char* dir_path,
uint32_t frame_id,
rkisp_effect_params_v20& ispParams,
SmartPtr<RkAiqSensorExpParamsProxy>& expParams,
SmartPtr<RkAiqAfInfoProxy>& afParams,
int working_mode)
{
FILE *fp = nullptr;
char file_name[64] = {0};
char buffer[256] = {0};
int32_t focusCode = 0;
int32_t zoomCode = 0;
/*
* rk_aiq_isp_meas_params_v20_t* ispMeasParams =
* static_cast<rk_aiq_isp_meas_params_v20_t*>(ispParams->data().ptr());
*/
snprintf(file_name, sizeof(file_name), "%s/meta_data", dir_path);
if(afParams.ptr()) {
focusCode = afParams->data()->focusCode;
zoomCode = afParams->data()->zoomCode;
}
fp = fopen(file_name, "ab+");
if (fp != nullptr) {
if (working_mode == RK_AIQ_ISP_HDR_MODE_3_FRAME_HDR || \
working_mode == RK_AIQ_ISP_HDR_MODE_3_LINE_HDR) {
if (CHECK_ISP_HW_V20()) {
#ifdef ISP_HW_V20
snprintf(buffer,
sizeof(buffer),
"frame%08u-l_m_s-gain[%08.5f_%08.5f_%08.5f]-time[%08.5f_%08.5f_%08.5f]-"
"awbGain[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
frame_id,
expParams->data()->aecExpInfo.HdrExp[2].exp_real_params.analog_gain,
expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.analog_gain,
expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.analog_gain,
expParams->data()->aecExpInfo.HdrExp[2].exp_real_params.integration_time,
expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.integration_time,
expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.integration_time,
ispParams.isp_params.others.awb_gain_cfg.gain_red,
ispParams.isp_params.others.awb_gain_cfg.gain_green_r,
ispParams.isp_params.others.awb_gain_cfg.gain_green_b,
ispParams.isp_params.others.awb_gain_cfg.gain_blue,
1,
focusCode,
zoomCode);
#endif
} else if (CHECK_ISP_HW_V21()) {
#ifdef ISP_HW_V21
snprintf(buffer,
sizeof(buffer),
"frame%08u-l_m_s-gain[%08.5f_%08.5f_%08.5f]-time[%08.5f_%08.5f_%08.5f]-"
"awbGain[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
frame_id,
expParams->data()->aecExpInfo.HdrExp[2].exp_real_params.analog_gain,
expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.analog_gain,
expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.analog_gain,
expParams->data()->aecExpInfo.HdrExp[2].exp_real_params.integration_time,
expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.integration_time,
expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.integration_time,
ispParams.isp_params_v21.others.awb_gain_cfg.gain0_red,
ispParams.isp_params_v21.others.awb_gain_cfg.gain0_green_r,
ispParams.isp_params_v21.others.awb_gain_cfg.gain0_green_b,
ispParams.isp_params_v21.others.awb_gain_cfg.gain0_blue,
1,
focusCode,
zoomCode);
#endif
} else if (CHECK_ISP_HW_V30()) {
#ifdef ISP_HW_V30
snprintf(buffer,
sizeof(buffer),
"frame%08u-l_m_s-gain[%08.5f_%08.5f_%08.5f]-time[%08.5f_%08.5f_%08.5f]-"
"awbGain[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
frame_id,
expParams->data()->aecExpInfo.HdrExp[2].exp_real_params.analog_gain,
expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.analog_gain,
expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.analog_gain,
expParams->data()->aecExpInfo.HdrExp[2].exp_real_params.integration_time,
expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.integration_time,
expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.integration_time,
ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_red,
ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_green_r,
ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_green_b,
ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_blue,
1,
focusCode,
zoomCode);
#endif
} else if (CHECK_ISP_HW_V32() || CHECK_ISP_HW_V32_LITE()) {
#if defined(ISP_HW_V32) || defined(ISP_HW_V32_LITE)
snprintf(buffer,
sizeof(buffer),
"frame%08u-l_m_s-gain[%08.5f_%08.5f_%08.5f]-time[%08.5f_%08.5f_%08.5f]-"
"awbGain0[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
frame_id,
expParams->data()->aecExpInfo.HdrExp[2].exp_real_params.analog_gain,
expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.analog_gain,
expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.analog_gain,
expParams->data()->aecExpInfo.HdrExp[2].exp_real_params.integration_time,
expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.integration_time,
expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.integration_time,
ispParams.awb_gain_cfg.gain0_red,
ispParams.awb_gain_cfg.gain0_green_r,
ispParams.awb_gain_cfg.gain0_green_b,
ispParams.awb_gain_cfg.gain0_blue,
1,
focusCode,
zoomCode);
#endif
} else if (working_mode == RK_AIQ_ISP_HDR_MODE_2_FRAME_HDR || \
working_mode == RK_AIQ_ISP_HDR_MODE_2_LINE_HDR) {
if (CHECK_ISP_HW_V20()) {
#ifdef ISP_HW_V20
snprintf(buffer,
sizeof(buffer),
"frame%08u-l_s-gain[%08.5f_%08.5f]-time[%08.5f_%08.5f]-"
"awbGain[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
frame_id,
expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.analog_gain,
expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.analog_gain,
expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.integration_time,
expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.integration_time,
ispParams.isp_params.others.awb_gain_cfg.gain_red,
ispParams.isp_params.others.awb_gain_cfg.gain_green_r,
ispParams.isp_params.others.awb_gain_cfg.gain_green_b,
ispParams.isp_params.others.awb_gain_cfg.gain_blue,
1,
focusCode,
zoomCode);
#endif
} else if (CHECK_ISP_HW_V21()) {
#ifdef ISP_HW_V21
snprintf(buffer,
sizeof(buffer),
"frame%08u-l_s-gain[%08.5f_%08.5f]-time[%08.5f_%08.5f]-"
"awbGain[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
frame_id,
expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.analog_gain,
expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.analog_gain,
expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.integration_time,
expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.integration_time,
ispParams.isp_params_v21.others.awb_gain_cfg.gain0_red,
ispParams.isp_params_v21.others.awb_gain_cfg.gain0_green_r,
ispParams.isp_params_v21.others.awb_gain_cfg.gain0_green_b,
ispParams.isp_params_v21.others.awb_gain_cfg.gain0_blue,
1,
focusCode,
zoomCode);
#endif
} else if (CHECK_ISP_HW_V30()) {
#ifdef ISP_HW_V30
snprintf(buffer,
sizeof(buffer),
"frame%08u-l_s-gain[%08.5f_%08.5f]-time[%08.5f_%08.5f]-"
"awbGain[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
frame_id,
expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.analog_gain,
expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.analog_gain,
expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.integration_time,
expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.integration_time,
ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_red,
ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_green_r,
ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_green_b,
ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_blue,
1,
focusCode,
zoomCode);
#endif
} else if (CHECK_ISP_HW_V32() || CHECK_ISP_HW_V32_LITE()) {
#if defined(ISP_HW_V32) || defined(ISP_HW_V32_LITE)
snprintf(buffer,
sizeof(buffer),
"frame%08u-l_s-gain[%08.5f_%08.5f]-time[%08.5f_%08.5f]-"
"awbGain0[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
frame_id,
expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.analog_gain,
expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.analog_gain,
expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.integration_time,
expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.integration_time,
ispParams.awb_gain_cfg.gain0_red,
ispParams.awb_gain_cfg.gain0_green_r,
ispParams.awb_gain_cfg.gain0_green_b,
ispParams.awb_gain_cfg.gain0_blue,
1,
focusCode,
zoomCode);
#endif
} else {
if (CHECK_ISP_HW_V20()) {
#ifdef ISP_HW_V20
snprintf(buffer,
sizeof(buffer),
"frame%08u-gain[%08.5f]-time[%08.5f]-"
"awbGain[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
frame_id,
expParams->data()->aecExpInfo.LinearExp.exp_real_params.analog_gain,
expParams->data()->aecExpInfo.LinearExp.exp_real_params.integration_time,
ispParams.isp_params.others.awb_gain_cfg.gain_red,
ispParams.isp_params.others.awb_gain_cfg.gain_green_r,
ispParams.isp_params.others.awb_gain_cfg.gain_green_b,
ispParams.isp_params.others.awb_gain_cfg.gain_blue,
1,
focusCode,
zoomCode);
#endif
} else if (CHECK_ISP_HW_V21()) {
#ifdef ISP_HW_V21
snprintf(buffer,
sizeof(buffer),
"frame%08u-gain[%08.5f]-time[%08.5f]-"
"awbGain[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
frame_id,
expParams->data()->aecExpInfo.LinearExp.exp_real_params.analog_gain,
expParams->data()->aecExpInfo.LinearExp.exp_real_params.integration_time,
ispParams.isp_params_v21.others.awb_gain_cfg.gain0_red,
ispParams.isp_params_v21.others.awb_gain_cfg.gain0_green_r,
ispParams.isp_params_v21.others.awb_gain_cfg.gain0_green_b,
ispParams.isp_params_v21.others.awb_gain_cfg.gain0_blue,
1,
focusCode,
zoomCode);
#endif
} else if (CHECK_ISP_HW_V30()) {
#ifdef ISP_HW_V30
snprintf(buffer,
sizeof(buffer),
"frame%08u-gain[%08.5f]-time[%08.5f]-"
"awbGain[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
frame_id,
expParams->data()->aecExpInfo.LinearExp.exp_real_params.analog_gain,
expParams->data()->aecExpInfo.LinearExp.exp_real_params.integration_time,
ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_red,
ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_green_r,
ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_green_b,
ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_blue,
1,
focusCode,
zoomCode);
#endif
} else if (CHECK_ISP_HW_V32() || CHECK_ISP_HW_V32_LITE()) {
#if defined(ISP_HW_V32) || defined(ISP_HW_V32_LITE)
snprintf(buffer,
sizeof(buffer),
"frame%08u-gain[%08.5f]-time[%08.5f]-"
"awbGain1[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
frame_id,
expParams->data()->aecExpInfo.LinearExp.exp_real_params.analog_gain,
expParams->data()->aecExpInfo.LinearExp.exp_real_params.integration_time,
ispParams.awb_gain_cfg.awb1_gain_r,
ispParams.awb_gain_cfg.awb1_gain_gr,
ispParams.awb_gain_cfg.awb1_gain_gb,
ispParams.awb_gain_cfg.awb1_gain_b,
1,
focusCode,
zoomCode);
#endif
}
}
}
}
fwrite((void *)buffer, strlen(buffer), 1, fp);
fflush(fp);
fclose(fp);
}
}
int CaptureRawData::calculate_stride_per_line(const struct capture_fmt& fmt,
uint32_t& bytesPerLine, SmartPtr<V4l2Device> dev)
{
uint32_t pixelsPerLine = 0, stridePerLine = 0;
/* The actual size stored in the memory */
// uint32_t actualBytesPerLine = 0;
bytesPerLine = sns_width * fmt.bpp[0] / 8;
pixelsPerLine = fmt.pcpp * DIV_ROUND_UP(sns_width, fmt.pcpp);
// actualBytesPerLine = pixelsPerLine * fmt.bpp[0] / 8;
#if 0
/* mipi wc(Word count) must be 4 byte aligned */
stridePerLine = 256 * DIV_ROUND_UP(actualBytesPerLine, 256);
#else
struct v4l2_format format;
memset(&format, 0, sizeof(format));
dev->get_format(format);
stridePerLine = format.fmt.pix_mp.plane_fmt[0].bytesperline;
#endif
LOGD_CAMHW_SUBM(CAPTURERAW_SUBM, "sns_width: %d, pixelsPerLine: %d, bytesPerLine: %d, stridePerLine: %d\n",
sns_width,
pixelsPerLine,
bytesPerLine,
stridePerLine);
return stridePerLine;
}
/*
* Refer to "Raw file structure" in the header of this file
*/
XCamReturn
CaptureRawData::write_frame_header_to_raw(FILE *fp, int dev_index,
int sequence, int working_mode, SmartPtr<V4l2Device> dev)
{
uint8_t buffer[128] = {0};
uint32_t stridePerLine = 0, bytesPerLine = 0;
const struct capture_fmt* fmt = nullptr;
uint8_t mode = 0;
uint8_t frame_type = 0, storage_type = 0;
if (fp == nullptr)
return XCAM_RETURN_ERROR_PARAM;
if ((fmt = find_fmt(pixelformat)))
stridePerLine = calculate_stride_per_line(*fmt, bytesPerLine, dev);
if (working_mode == RK_AIQ_ISP_HDR_MODE_3_FRAME_HDR || \
working_mode == RK_AIQ_ISP_HDR_MODE_3_LINE_HDR) {
mode = 3;
frame_type = dev_index == 0 ? 1 : dev_index == 1 ? 2 : 3;
} else if (working_mode == RK_AIQ_ISP_HDR_MODE_2_FRAME_HDR || \
working_mode == RK_AIQ_ISP_HDR_MODE_2_LINE_HDR) {
mode = 2;
frame_type = dev_index == 0 ? 1 : 3;
} else {
mode = 1;
}
_stride_perline = stridePerLine;
*((uint16_t* )buffer) = RAW_FILE_IDENT; // Identifier
*((uint16_t* )(buffer + 2)) = HEADER_LEN; // Header length
*((uint32_t* )(buffer + 4)) = sequence; // Frame number
*((uint16_t* )(buffer + 8)) = sns_width; // Image width
*((uint16_t* )(buffer + 10)) = sns_height; // Image height
*(buffer + 12) = fmt->bpp[0]; // Bit depth
*(buffer + 13) = fmt->bayer_fmt; // Bayer format
*(buffer + 14) = mode; // Number of HDR frame
*(buffer + 15) = frame_type; // Current frame type
*(buffer + 16) = storage_type; // Storage type
*((uint16_t* )(buffer + 17)) = stridePerLine; // Line stride
*((uint16_t* )(buffer + 19)) = bytesPerLine; // Effective line stride
fwrite(buffer, sizeof(buffer), 1, fp);
fflush(fp);
LOGV_CAMHW_SUBM(CAPTURERAW_SUBM, "frame%d: image rect: %dx%d, %d bit depth, Bayer fmt: %d, "
"hdr frame number: %d, frame type: %d, Storage type: %d, "
"line stride: %d, Effective line stride: %d\n",
sequence, sns_width, sns_height,
fmt->bpp[0], fmt->bayer_fmt, mode,
frame_type, storage_type, stridePerLine,
bytesPerLine);
return XCAM_RETURN_NO_ERROR;
}
XCamReturn
CaptureRawData::write_raw_to_file(FILE* fp, int dev_index,
int sequence, void* userptr, int size)
{
if (fp == nullptr)
return XCAM_RETURN_ERROR_PARAM;
fwrite(userptr, size, 1, fp);
fflush(fp);
if (!dev_index) {
for (int i = 0; i < _capture_raw_num; i++)
printf(">");
printf("\n");
}
LOGV_CAMHW_SUBM(CAPTURERAW_SUBM, "dev(%d) write frame%d raw\n", dev_index, sequence);
return XCAM_RETURN_NO_ERROR;
}
void
CaptureRawData::write_reg_to_file(uint32_t base_addr, uint32_t offset_addr,
int len, int sequence)
{
}
XCamReturn
CaptureRawData::creat_raw_dir(const char* path)
{
time_t now;
struct tm* timenow;
struct timeval tv;
struct timezone tz;
if (!path)
return XCAM_RETURN_ERROR_FAILED;
gettimeofday(&tv, &tz);
time(&now);
timenow = localtime(&now);
if (access(path, W_OK) == -1) {
if (mkdir(path, 0755) < 0) {
LOGE_CAMHW_SUBM(CAPTURERAW_SUBM, "mkdir %s error(%s)!\n",
path, strerror(errno));
return XCAM_RETURN_ERROR_FILE;
}
}
snprintf(raw_dir_path, sizeof(raw_dir_path), "%s/Cam%d-raw_%04d-%02d-%02d_%02d-%02d-%02d-%03ld",
path,
_camId,
timenow->tm_year + 1900,
timenow->tm_mon + 1,
timenow->tm_mday,
timenow->tm_hour,
timenow->tm_min,
timenow->tm_sec,
tv.tv_usec/1000);
LOGV_CAMHW_SUBM(CAPTURERAW_SUBM, "mkdir %s for capturing %d frames raw!\n",
raw_dir_path, _capture_raw_num);
if(mkdir(raw_dir_path, 0755) < 0) {
LOGE_CAMHW_SUBM(CAPTURERAW_SUBM, "mkdir %s error(%s)!!!\n",
raw_dir_path, strerror(errno));
return XCAM_RETURN_ERROR_PARAM;
}
_is_raw_dir_exist = true;
return XCAM_RETURN_ERROR_PARAM;
}
XCamReturn
CaptureRawData::notify_capture_raw()
{
SmartLock locker(_capture_image_mutex);
_capture_image_cond.broadcast();
return XCAM_RETURN_NO_ERROR;
}
XCamReturn
CaptureRawData::capture_raw_ctl(capture_raw_t type, int count, const char* capture_dir, char* output_dir)
{
XCamReturn ret = XCAM_RETURN_NO_ERROR;
_capture_raw_type = type;
if (_capture_raw_type == CAPTURE_RAW_SYNC) {
if (capture_dir != nullptr)
snprintf(user_set_raw_dir, sizeof( user_set_raw_dir),
"%s/capture_image", capture_dir);
else
strcpy(user_set_raw_dir, DEFAULT_CAPTURE_RAW_PATH);
char cmd_buffer[32] = {0};
snprintf(cmd_buffer, sizeof(cmd_buffer),
"echo %d > %s_c%d",
count, CAPTURE_CNT_FILENAME, _camId);
system(cmd_buffer);
_capture_image_mutex.lock();
if (_capture_image_cond.timedwait(_capture_image_mutex, 30000000) != 0)
ret = XCAM_RETURN_ERROR_TIMEOUT;
else {
// TODO(FIX ME): mistaken use of strncpy.
strcpy(output_dir, raw_dir_path);
}
_capture_image_mutex.unlock();
} else if (_capture_raw_type == CAPTURE_RAW_AND_YUV_SYNC) {
LOGD_CAMHW_SUBM(CAPTURERAW_SUBM, "capture raw and yuv images simultaneously!");
}
return ret;
}
void CaptureRawData::save_metadata_and_register
(
uint32_t frameId,
rkisp_effect_params_v20& ispParams,
SmartPtr<RkAiqSensorExpParamsProxy>& expParams,
SmartPtr<RkAiqAfInfoProxy>& afParams,
int working_mode
)
{
if (_capture_metadata_num > 0) {
char file_name[32] = {0};
int capture_cnt = 0;
uint32_t rawFrmId = 0;
snprintf(file_name, sizeof(file_name), "%s", CAPTURE_CNT_FILENAME);
bool ret = get_value_from_file(file_name, capture_cnt, rawFrmId);
if (!ret) {
// test multi cam mode
snprintf(file_name, sizeof(file_name), "%.50s_c%d", CAPTURE_CNT_FILENAME, _camId);
get_value_from_file(file_name, capture_cnt, rawFrmId);
}
LOGD_CAMHW_SUBM(CAPTURERAW_SUBM, "rawFrmId: %d, sequence: %d, _capture_metadata_num: %d\n",
rawFrmId, frameId,
_capture_metadata_num);
if (_is_raw_dir_exist && frameId >= rawFrmId && expParams.ptr()) {
#ifdef WRITE_ISP_REG
write_reg_to_file(ISP_REGS_BASE, 0x0, 0x6000, frameId);
#endif
#ifdef WRITE_ISPP_REG
write_reg_to_file(ISPP_REGS_BASE, 0x0, 0xc94, frameId);
#endif
write_metadata_to_file(raw_dir_path,
frameId,
ispParams, expParams, afParams,working_mode);
_capture_metadata_num--;
if (!_capture_metadata_num) {
_is_raw_dir_exist = false;
if (_capture_raw_type == CAPTURE_RAW_SYNC) {
_capture_image_mutex.lock();
_capture_image_cond.broadcast();
_capture_image_mutex.unlock();
}
LOGD_CAMHW_SUBM(CAPTURERAW_SUBM, "stop capturing raw!\n");
}
}
}
}
} //namspace RkCam