/* 
 | 
 *  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) 
 | 
    , _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) 
 | 
{ 
 | 
} 
 | 
  
 | 
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; 
 | 
  
 | 
    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 %8d\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; 
 | 
        get_value_from_file(file_name, _capture_raw_num, rawFrmId); 
 | 
  
 | 
        if (_capture_raw_num > 0) { 
 | 
            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), "%s", 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) { 
 | 
            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%d_%dx%d_%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%d_%dx%d_%s.raw", 
 | 
                         raw_dir_path, 
 | 
                         sequence, 
 | 
                         sns_width, 
 | 
                         sns_height, 
 | 
                         i == 0 ? "short" : "long"); 
 | 
            else 
 | 
                snprintf(raw_name, sizeof(raw_name), 
 | 
                         "%s/frame%d_%dx%d_%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<RkAiqExpParamsProxy>& 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()) 
 | 
                snprintf(buffer, 
 | 
                         sizeof(buffer), 
 | 
                         "frame%08d-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); 
 | 
            else if (CHECK_ISP_HW_V21()) 
 | 
                snprintf(buffer, 
 | 
                         sizeof(buffer), 
 | 
                         "frame%08d-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); 
 | 
        } 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()) 
 | 
                snprintf(buffer, 
 | 
                         sizeof(buffer), 
 | 
                         "frame%08d-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); 
 | 
            else if (CHECK_ISP_HW_V21()) 
 | 
                snprintf(buffer, 
 | 
                         sizeof(buffer), 
 | 
                         "frame%08d-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); 
 | 
        } else { 
 | 
            if (CHECK_ISP_HW_V20()) 
 | 
                snprintf(buffer, 
 | 
                         sizeof(buffer), 
 | 
                         "frame%08d-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); 
 | 
            else if (CHECK_ISP_HW_V21()) 
 | 
                snprintf(buffer, 
 | 
                         sizeof(buffer), 
 | 
                         "frame%08d-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); 
 | 
        } 
 | 
  
 | 
        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, "write frame%d raw\n", 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; 
 | 
  
 | 
    if (!path) 
 | 
        return XCAM_RETURN_ERROR_FAILED; 
 | 
  
 | 
    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_PARAM; 
 | 
    } 
 | 
  
 | 
    snprintf(raw_dir_path, sizeof(raw_dir_path), "%s/raw_%04d-%02d-%02d_%02d-%02d-%02d", 
 | 
             path, 
 | 
             timenow->tm_year + 1900, 
 | 
             timenow->tm_mon + 1, 
 | 
             timenow->tm_mday, 
 | 
             timenow->tm_hour, 
 | 
             timenow->tm_min, 
 | 
             timenow->tm_sec); 
 | 
  
 | 
    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", 
 | 
                 count, CAPTURE_CNT_FILENAME); 
 | 
        system(cmd_buffer); 
 | 
  
 | 
        _capture_image_mutex.lock(); 
 | 
        if (_capture_image_cond.timedwait(_capture_image_mutex, 30000000) != 0) 
 | 
            ret = XCAM_RETURN_ERROR_TIMEOUT; 
 | 
        else 
 | 
            strncpy(output_dir, raw_dir_path, strlen(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<RkAiqExpParamsProxy>& 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); 
 | 
        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 
 |