1 /*
2 * Copyright (c) 2021 Rockchip Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17 #include <sys/stat.h>
18 #include <sys/types.h>
19 #include <fcntl.h>
20 #include <stdlib.h>
21 #include "rk_aiq_comm.h"
22 #include "CaptureRawData.h"
23
24 #ifndef DIV_ROUND_UP
25 #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
26 #endif
27
28 #ifdef ANDROID_OS
29 #define DEFAULT_CAPTURE_RAW_PATH "/data/capture_image"
30 #define CAPTURE_CNT_FILENAME "/data/.capture_cnt"
31 #else
32 #define DEFAULT_CAPTURE_RAW_PATH "/tmp/capture_image"
33 #define CAPTURE_CNT_FILENAME "/tmp/.capture_cnt"
34 #endif
35
36 #define WRITE_RAW_FILE_HEADER
37 /*
38 * #define WRITE_ISP_REG
39 * #define WRITE_ISPP_REG
40 */
41 #define ISP_REGS_BASE 0xffb50000
42 #define ISPP_REGS_BASE 0xffb60000
43
44 #define RAW_FILE_IDENT 0x8080
45 #define HEADER_LEN 128U
46
47 /*
48 * Raw file structure:
49 *
50 +------------+-----------------+-------------+-----------------+---------------------------+
51 | ITEM | PARAMETER | DATA TYPE | LENGTH(Bytes) | DESCRIPTION |
52 +------------+-----------------+-------------+-----------------+---------------------------+
53 | | Identifier | uint16_t | 2 | fixed 0x8080 |
54 | +-----------------+-------------+-----------------+---------------------------+
55 | | Header length | uint16_t | 2 | fixed 128U |
56 | +-----------------+-------------+-----------------+---------------------------+
57 | | Frame index | uint32_t | 4 | |
58 | +-----------------+-------------+-----------------+---------------------------+
59 | | Width | uint16_t | 2 | image width |
60 | +-----------------+-------------+-----------------+---------------------------+
61 | | Height | uint16_t | 2 | image height |
62 | +-----------------+-------------+-----------------+---------------------------+
63 | | Bit depth | uint8_t | 1 | image bit depth |
64 | +-----------------+-------------+-----------------+---------------------------+
65 | | | | | 0: BGGR; 1: GBRG; |
66 | | Bayer format | uint8_t | 1 | 2: GRBG; 3: RGGB; |
67 | +-----------------+-------------+-----------------+---------------------------+
68 | | | | | 1: linear |
69 | FRAME | Number of HDR | | | 2: long + short |
70 | HEADER | frame | uint8_t | 1 | 3: long + mid + short |
71 | +-----------------+-------------+-----------------+---------------------------+
72 | | | | | 1: short |
73 | | Current frame | | | 2: mid |
74 | | type | uint8_t | 1 | 3: long |
75 | +-----------------+-------------+-----------------+---------------------------+
76 | | Storage type | uint8_t | 1 | 0: packed; 1: unpacked |
77 | +-----------------+-------------+-----------------+---------------------------+
78 | | Line stride | uint16_t | 2 | In bytes |
79 | +-----------------+-------------+-----------------+---------------------------+
80 | | Effective | | | |
81 | | line stride | uint16_t | 2 | In bytes |
82 | +-----------------+-------------+-----------------+---------------------------+
83 | | Reserved | uint8_t | 107 | |
84 +------------+-----------------+-------------+-----------------+---------------------------+
85 | | | | | |
86 | RAW DATA | RAW DATA | RAW | W * H * bpp | RAW DATA |
87 | | | | | |
88 +------------+-----------------+-------------+-----------------+---------------------------+
89
90 */
91
92 /*
93 * the structure of measuure parameters from isp in meta_data file:
94 *
95 * "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]"
96 *
97 */
98
99 namespace RkCam {
100
101 const struct capture_fmt CaptureRawData::csirx_fmts[] =
102 {
103 /* raw */
104 {
105 .fourcc = V4L2_PIX_FMT_SRGGB8,
106 .bayer_fmt = 3,
107 .pcpp = 1,
108 .bpp = { 8 },
109 }, {
110 .fourcc = V4L2_PIX_FMT_SGRBG8,
111 .bayer_fmt = 2,
112 .pcpp = 1,
113 .bpp = { 8 },
114 }, {
115 .fourcc = V4L2_PIX_FMT_SGBRG8,
116 .bayer_fmt = 1,
117 .pcpp = 1,
118 .bpp = { 8 },
119 }, {
120 .fourcc = V4L2_PIX_FMT_SBGGR8,
121 .bayer_fmt = 0,
122 .pcpp = 1,
123 .bpp = { 8 },
124 }, {
125 .fourcc = V4L2_PIX_FMT_SRGGB10,
126 .bayer_fmt = 3,
127 .pcpp = 4,
128 .bpp = { 10 },
129 }, {
130 .fourcc = V4L2_PIX_FMT_SGRBG10,
131 .bayer_fmt = 2,
132 .pcpp = 4,
133 .bpp = { 10 },
134 }, {
135 .fourcc = V4L2_PIX_FMT_SGBRG10,
136 .bayer_fmt = 1,
137 .pcpp = 4,
138 .bpp = { 10 },
139 }, {
140 .fourcc = V4L2_PIX_FMT_SBGGR10,
141 .bayer_fmt = 0,
142 .pcpp = 4,
143 .bpp = { 10 },
144 }, {
145 .fourcc = V4L2_PIX_FMT_SRGGB12,
146 .bayer_fmt = 3,
147 .pcpp = 2,
148 .bpp = { 12 },
149 }, {
150 .fourcc = V4L2_PIX_FMT_SGRBG12,
151 .bayer_fmt = 2,
152 .pcpp = 2,
153 .bpp = { 12 },
154 }, {
155 .fourcc = V4L2_PIX_FMT_SGBRG12,
156 .bayer_fmt = 1,
157 .pcpp = 2,
158 .bpp = { 12 },
159 }, {
160 .fourcc = V4L2_PIX_FMT_SBGGR12,
161 .bayer_fmt = 0,
162 .pcpp = 2,
163 .bpp = { 12 },
164 },
165 };
166
CaptureRawData()167 CaptureRawData::CaptureRawData ()
168 : sns_width(0)
169 , sns_height(0)
170 , pixelformat(0)
171 , _stride_perline(0)
172 , _is_raw_dir_exist(false)
173 , _is_capture_raw(false)
174 , _capture_raw_num(0)
175 , _capture_metadata_num(0)
176 , _capture_image_mutex(false)
177 , _capture_image_cond(false)
178 , _capture_raw_type(CAPTURE_RAW_ASYNC)
179 , _camId(-1)
180 {
181 }
182
CaptureRawData(int32_t camId)183 CaptureRawData::CaptureRawData(int32_t camId)
184 : sns_width(0)
185 , sns_height(0)
186 , pixelformat(0)
187 , _stride_perline(0)
188 , _is_raw_dir_exist(false)
189 , _is_capture_raw(false)
190 , _capture_raw_num(0)
191 , _capture_metadata_num(0)
192 , _capture_image_mutex(false)
193 , _capture_image_cond(false)
194 , _capture_raw_type(CAPTURE_RAW_ASYNC)
195 , _camId(camId)
196 {
197 }
198
~CaptureRawData()199 CaptureRawData::~CaptureRawData ()
200 {
201 }
202
find_fmt(const uint32_t pixelformat)203 const struct capture_fmt* CaptureRawData::find_fmt(const uint32_t pixelformat)
204 {
205 const struct capture_fmt *fmt;
206 unsigned int i;
207
208 for (i = 0; i < sizeof(csirx_fmts); i++) {
209 fmt = &csirx_fmts[i];
210 if (fmt->fourcc == pixelformat)
211 return fmt;
212 }
213
214 return NULL;
215 }
216
217 bool
get_value_from_file(const char * path,int & value,uint32_t & frameId)218 CaptureRawData::get_value_from_file(const char* path, int& value, uint32_t& frameId)
219 {
220 const char *delim = " ";
221 char buffer[16] = {0};
222 int fp;
223
224 fp = open(path, O_RDONLY | O_SYNC);
225 if (fp != -1) {
226 if (read(fp, buffer, sizeof(buffer)) <= 0) {
227 LOGV_CAMHW_SUBM(CAPTURERAW_SUBM, "%s read %s failed!\n", __func__, path);
228 } else {
229 char *p = nullptr;
230
231 p = strtok(buffer, delim);
232 if (p != nullptr) {
233 value = atoi(p);
234 p = strtok(nullptr, delim);
235 if (p != nullptr)
236 frameId = atoi(p);
237 }
238 }
239 close(fp);
240 LOGV_CAMHW_SUBM(CAPTURERAW_SUBM, "value: %d, frameId: %d\n", value, frameId);
241 return true;
242 }
243
244 return false;
245 }
246
247
248 bool
set_value_to_file(const char * path,int value,uint32_t sequence)249 CaptureRawData::set_value_to_file(const char* path, int value, uint32_t sequence)
250 {
251 char buffer[16] = {0};
252 int fp;
253 if (access(path, F_OK) == -1)
254 return false;
255 fp = open(path, O_CREAT | O_RDWR | O_SYNC, S_IRWXU | S_IRUSR | S_IXUSR | S_IROTH | S_IXOTH);
256 if (fp != -1) {
257 ftruncate(fp, 0);
258 lseek(fp, 0, SEEK_SET);
259 snprintf(buffer, sizeof(buffer), "%3d %8d\n", _capture_raw_num, sequence);
260 if (write(fp, buffer, sizeof(buffer)) <= 0) {
261 LOGW_CAMHW_SUBM(CAPTURERAW_SUBM, "%s write %s failed!\n", __func__, path);
262 }
263 close(fp);
264 return true;
265 }
266
267 return false;
268 }
269
detect_capture_raw_status(uint32_t sequence,bool first_trigger)270 int CaptureRawData::detect_capture_raw_status(uint32_t sequence, bool first_trigger)
271 {
272 char file_name[64] = {0};
273 snprintf(file_name, sizeof(file_name), "%s", CAPTURE_CNT_FILENAME);
274 if (!_is_capture_raw) {
275 uint32_t rawFrmId = 0;
276
277 bool ret = get_value_from_file(file_name, _capture_raw_num, rawFrmId);
278 if (!ret) {
279 // test multi cam mode
280 snprintf(file_name, sizeof(file_name), "%.50s_c%d", CAPTURE_CNT_FILENAME, _camId);
281 get_value_from_file(file_name, _capture_raw_num, rawFrmId);
282 }
283
284 if (_capture_raw_num > 0) {
285 bool ret = set_value_to_file(file_name, _capture_raw_num, sequence);
286 if (!ret) {
287 // test multi cam mode
288 snprintf(file_name, sizeof(file_name), "%.50s_c%d", CAPTURE_CNT_FILENAME, _camId);
289 set_value_to_file(file_name, _capture_raw_num, sequence);
290 }
291 _is_capture_raw = true;
292 _capture_metadata_num = _capture_raw_num;
293 if (first_trigger)
294 ++_capture_metadata_num;
295 }
296 }
297
298 return 0;
299 }
300
update_capture_raw_status(bool first_trigger)301 int CaptureRawData::update_capture_raw_status(bool first_trigger)
302 {
303 char file_name[64] = {0};
304 snprintf(file_name, sizeof(file_name), "%.63s", CAPTURE_CNT_FILENAME);
305 if (_is_capture_raw && !first_trigger) {
306 if (_capture_raw_type == CAPTURE_RAW_AND_YUV_SYNC) {
307 _capture_image_mutex.lock();
308 _capture_image_cond.timedwait(_capture_image_mutex, 3000000);
309 _capture_image_mutex.unlock();
310 }
311
312 if (!--_capture_raw_num) {
313 bool ret = set_value_to_file(file_name, _capture_raw_num);
314 if (!ret) {
315 // test multi cam mode
316 snprintf(file_name, sizeof(file_name), "%.50s_c%d", CAPTURE_CNT_FILENAME, _camId);
317 set_value_to_file(file_name, _capture_raw_num);
318 }
319 _is_capture_raw = false;
320 }
321 }
322
323 return 0;
324 }
325
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)326 int CaptureRawData::dynamic_capture_raw
327 (
328 int i,
329 uint32_t sequence,
330 SmartPtr<V4l2BufferProxy> buf_proxy,
331 SmartPtr<V4l2Buffer> &v4l2buf,
332 int mipi_dev_max,
333 int working_mode,
334 SmartPtr<V4l2Device> dev
335 )
336 {
337 if (_is_capture_raw && _capture_raw_num > 0) {
338 if (!_is_raw_dir_exist) {
339 if (_capture_raw_type == CAPTURE_RAW_SYNC)
340 creat_raw_dir(user_set_raw_dir);
341 else
342 creat_raw_dir(DEFAULT_CAPTURE_RAW_PATH);
343 }
344
345 if (_is_raw_dir_exist) {
346 char raw_name[128] = {0};
347 FILE *fp = nullptr;
348 sns_width = v4l2buf->get_format().fmt.pix.width;
349 sns_height = v4l2buf->get_format().fmt.pix.height;
350 pixelformat = v4l2buf->get_format().fmt.pix.pixelformat;
351 XCAM_STATIC_PROFILING_START(write_raw);
352 memset(raw_name, 0, sizeof(raw_name));
353 if (mipi_dev_max == 1)
354 snprintf(raw_name, sizeof(raw_name),
355 "%s/frame%d_%dx%d_%s.raw",
356 raw_dir_path,
357 sequence,
358 sns_width,
359 sns_height,
360 "normal");
361 else if (mipi_dev_max == 2)
362 snprintf(raw_name, sizeof(raw_name),
363 "%s/frame%d_%dx%d_%s.raw",
364 raw_dir_path,
365 sequence,
366 sns_width,
367 sns_height,
368 i == 0 ? "short" : "long");
369 else
370 snprintf(raw_name, sizeof(raw_name),
371 "%s/frame%d_%dx%d_%s.raw",
372 raw_dir_path,
373 sequence,
374 sns_width,
375 sns_height,
376 i == 0 ? "short" : i == 1 ? "middle" : "long");
377
378 fp = fopen(raw_name, "wb+");
379 if (fp != nullptr) {
380 int size = 0;
381 #ifdef WRITE_RAW_FILE_HEADER
382 write_frame_header_to_raw(fp, i, sequence, working_mode, dev);
383 #endif
384
385 #if 0
386 size = v4l2buf->get_buf().m.planes[0].length;
387 #else
388 /* raw image size compatible with ISP expansion line mode */
389 size = _stride_perline * sns_height;
390 #endif
391 write_raw_to_file(fp, i, sequence,
392 (void *)(buf_proxy->get_v4l2_userptr()),
393 size);
394 fclose(fp);
395 }
396 XCAM_STATIC_PROFILING_END(write_raw, 0);
397 }
398 }
399
400 return 0;
401 }
402
403 void
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)404 CaptureRawData::write_metadata_to_file(const char* dir_path,
405 uint32_t frame_id,
406 rkisp_effect_params_v20& ispParams,
407 SmartPtr<RkAiqSensorExpParamsProxy>& expParams,
408 SmartPtr<RkAiqAfInfoProxy>& afParams,
409 int working_mode)
410 {
411 FILE *fp = nullptr;
412 char file_name[64] = {0};
413 char buffer[256] = {0};
414 int32_t focusCode = 0;
415 int32_t zoomCode = 0;
416 /*
417 * rk_aiq_isp_meas_params_v20_t* ispMeasParams =
418 * static_cast<rk_aiq_isp_meas_params_v20_t*>(ispParams->data().ptr());
419 */
420
421 snprintf(file_name, sizeof(file_name), "%s/meta_data", dir_path);
422
423 if(afParams.ptr()) {
424 focusCode = afParams->data()->focusCode;
425 zoomCode = afParams->data()->zoomCode;
426 }
427
428 fp = fopen(file_name, "ab+");
429 if (fp != nullptr) {
430 if (working_mode == RK_AIQ_ISP_HDR_MODE_3_FRAME_HDR || \
431 working_mode == RK_AIQ_ISP_HDR_MODE_3_LINE_HDR) {
432 if (CHECK_ISP_HW_V20()) {
433 #ifdef ISP_HW_V20
434 snprintf(buffer,
435 sizeof(buffer),
436 "frame%08d-l_m_s-gain[%08.5f_%08.5f_%08.5f]-time[%08.5f_%08.5f_%08.5f]-"
437 "awbGain[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
438 frame_id,
439 expParams->data()->aecExpInfo.HdrExp[2].exp_real_params.analog_gain,
440 expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.analog_gain,
441 expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.analog_gain,
442 expParams->data()->aecExpInfo.HdrExp[2].exp_real_params.integration_time,
443 expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.integration_time,
444 expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.integration_time,
445 ispParams.isp_params.others.awb_gain_cfg.gain_red,
446 ispParams.isp_params.others.awb_gain_cfg.gain_green_r,
447 ispParams.isp_params.others.awb_gain_cfg.gain_green_b,
448 ispParams.isp_params.others.awb_gain_cfg.gain_blue,
449 1,
450 focusCode,
451 zoomCode);
452 #endif
453 } else if (CHECK_ISP_HW_V21()) {
454 #ifdef ISP_HW_V21
455 snprintf(buffer,
456 sizeof(buffer),
457 "frame%08d-l_m_s-gain[%08.5f_%08.5f_%08.5f]-time[%08.5f_%08.5f_%08.5f]-"
458 "awbGain[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
459 frame_id,
460 expParams->data()->aecExpInfo.HdrExp[2].exp_real_params.analog_gain,
461 expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.analog_gain,
462 expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.analog_gain,
463 expParams->data()->aecExpInfo.HdrExp[2].exp_real_params.integration_time,
464 expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.integration_time,
465 expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.integration_time,
466 ispParams.isp_params_v21.others.awb_gain_cfg.gain0_red,
467 ispParams.isp_params_v21.others.awb_gain_cfg.gain0_green_r,
468 ispParams.isp_params_v21.others.awb_gain_cfg.gain0_green_b,
469 ispParams.isp_params_v21.others.awb_gain_cfg.gain0_blue,
470 1,
471 focusCode,
472 zoomCode);
473 #endif
474 } else if (CHECK_ISP_HW_V30()) {
475 #ifdef ISP_HW_V30
476 snprintf(buffer,
477 sizeof(buffer),
478 "frame%08d-l_m_s-gain[%08.5f_%08.5f_%08.5f]-time[%08.5f_%08.5f_%08.5f]-"
479 "awbGain[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
480 frame_id,
481 expParams->data()->aecExpInfo.HdrExp[2].exp_real_params.analog_gain,
482 expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.analog_gain,
483 expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.analog_gain,
484 expParams->data()->aecExpInfo.HdrExp[2].exp_real_params.integration_time,
485 expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.integration_time,
486 expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.integration_time,
487 ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_red,
488 ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_green_r,
489 ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_green_b,
490 ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_blue,
491 1,
492 focusCode,
493 zoomCode);
494 #endif
495 } else if (CHECK_ISP_HW_V32() || CHECK_ISP_HW_V32_LITE()) {
496 #if defined(ISP_HW_V32) || defined(ISP_HW_V32_LITE)
497 snprintf(buffer,
498 sizeof(buffer),
499 "frame%08d-l_m_s-gain[%08.5f_%08.5f_%08.5f]-time[%08.5f_%08.5f_%08.5f]-"
500 "awbGain0[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
501 frame_id,
502 expParams->data()->aecExpInfo.HdrExp[2].exp_real_params.analog_gain,
503 expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.analog_gain,
504 expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.analog_gain,
505 expParams->data()->aecExpInfo.HdrExp[2].exp_real_params.integration_time,
506 expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.integration_time,
507 expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.integration_time,
508 ispParams.awb_gain_cfg.gain0_red,
509 ispParams.awb_gain_cfg.gain0_green_r,
510 ispParams.awb_gain_cfg.gain0_green_b,
511 ispParams.awb_gain_cfg.gain0_blue,
512 1,
513 focusCode,
514 zoomCode);
515 #endif
516 } else if (working_mode == RK_AIQ_ISP_HDR_MODE_2_FRAME_HDR || \
517 working_mode == RK_AIQ_ISP_HDR_MODE_2_LINE_HDR) {
518 if (CHECK_ISP_HW_V20()) {
519 #ifdef ISP_HW_V20
520 snprintf(buffer,
521 sizeof(buffer),
522 "frame%08d-l_s-gain[%08.5f_%08.5f]-time[%08.5f_%08.5f]-"
523 "awbGain[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
524 frame_id,
525 expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.analog_gain,
526 expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.analog_gain,
527 expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.integration_time,
528 expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.integration_time,
529 ispParams.isp_params.others.awb_gain_cfg.gain_red,
530 ispParams.isp_params.others.awb_gain_cfg.gain_green_r,
531 ispParams.isp_params.others.awb_gain_cfg.gain_green_b,
532 ispParams.isp_params.others.awb_gain_cfg.gain_blue,
533 1,
534 focusCode,
535 zoomCode);
536 #endif
537 } else if (CHECK_ISP_HW_V21()) {
538 #ifdef ISP_HW_V21
539 snprintf(buffer,
540 sizeof(buffer),
541 "frame%08d-l_s-gain[%08.5f_%08.5f]-time[%08.5f_%08.5f]-"
542 "awbGain[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
543 frame_id,
544 expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.analog_gain,
545 expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.analog_gain,
546 expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.integration_time,
547 expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.integration_time,
548 ispParams.isp_params_v21.others.awb_gain_cfg.gain0_red,
549 ispParams.isp_params_v21.others.awb_gain_cfg.gain0_green_r,
550 ispParams.isp_params_v21.others.awb_gain_cfg.gain0_green_b,
551 ispParams.isp_params_v21.others.awb_gain_cfg.gain0_blue,
552 1,
553 focusCode,
554 zoomCode);
555 #endif
556 } else if (CHECK_ISP_HW_V30()) {
557 #ifdef ISP_HW_V30
558 snprintf(buffer,
559 sizeof(buffer),
560 "frame%08d-l_s-gain[%08.5f_%08.5f]-time[%08.5f_%08.5f]-"
561 "awbGain[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
562 frame_id,
563 expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.analog_gain,
564 expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.analog_gain,
565 expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.integration_time,
566 expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.integration_time,
567 ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_red,
568 ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_green_r,
569 ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_green_b,
570 ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_blue,
571 1,
572 focusCode,
573 zoomCode);
574 #endif
575 } else if (CHECK_ISP_HW_V32() || CHECK_ISP_HW_V32_LITE()) {
576 #if defined(ISP_HW_V32) || defined(ISP_HW_V32_LITE)
577 snprintf(buffer,
578 sizeof(buffer),
579 "frame%08d-l_s-gain[%08.5f_%08.5f]-time[%08.5f_%08.5f]-"
580 "awbGain0[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
581 frame_id,
582 expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.analog_gain,
583 expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.analog_gain,
584 expParams->data()->aecExpInfo.HdrExp[1].exp_real_params.integration_time,
585 expParams->data()->aecExpInfo.HdrExp[0].exp_real_params.integration_time,
586 ispParams.awb_gain_cfg.gain0_red,
587 ispParams.awb_gain_cfg.gain0_green_r,
588 ispParams.awb_gain_cfg.gain0_green_b,
589 ispParams.awb_gain_cfg.gain0_blue,
590 1,
591 focusCode,
592 zoomCode);
593 #endif
594 } else {
595 if (CHECK_ISP_HW_V20()) {
596 #ifdef ISP_HW_V20
597 snprintf(buffer,
598 sizeof(buffer),
599 "frame%08d-gain[%08.5f]-time[%08.5f]-"
600 "awbGain[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
601 frame_id,
602 expParams->data()->aecExpInfo.LinearExp.exp_real_params.analog_gain,
603 expParams->data()->aecExpInfo.LinearExp.exp_real_params.integration_time,
604 ispParams.isp_params.others.awb_gain_cfg.gain_red,
605 ispParams.isp_params.others.awb_gain_cfg.gain_green_r,
606 ispParams.isp_params.others.awb_gain_cfg.gain_green_b,
607 ispParams.isp_params.others.awb_gain_cfg.gain_blue,
608 1,
609 focusCode,
610 zoomCode);
611 #endif
612 } else if (CHECK_ISP_HW_V21()) {
613 #ifdef ISP_HW_V21
614 snprintf(buffer,
615 sizeof(buffer),
616 "frame%08d-gain[%08.5f]-time[%08.5f]-"
617 "awbGain[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
618 frame_id,
619 expParams->data()->aecExpInfo.LinearExp.exp_real_params.analog_gain,
620 expParams->data()->aecExpInfo.LinearExp.exp_real_params.integration_time,
621 ispParams.isp_params_v21.others.awb_gain_cfg.gain0_red,
622 ispParams.isp_params_v21.others.awb_gain_cfg.gain0_green_r,
623 ispParams.isp_params_v21.others.awb_gain_cfg.gain0_green_b,
624 ispParams.isp_params_v21.others.awb_gain_cfg.gain0_blue,
625 1,
626 focusCode,
627 zoomCode);
628 #endif
629 } else if (CHECK_ISP_HW_V30()) {
630 #ifdef ISP_HW_V30
631 snprintf(buffer,
632 sizeof(buffer),
633 "frame%08d-gain[%08.5f]-time[%08.5f]-"
634 "awbGain[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
635 frame_id,
636 expParams->data()->aecExpInfo.LinearExp.exp_real_params.analog_gain,
637 expParams->data()->aecExpInfo.LinearExp.exp_real_params.integration_time,
638 ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_red,
639 ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_green_r,
640 ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_green_b,
641 ispParams.isp_params_v3x[0].others.awb_gain_cfg.gain0_blue,
642 1,
643 focusCode,
644 zoomCode);
645 #endif
646 } else if (CHECK_ISP_HW_V32() || CHECK_ISP_HW_V32_LITE()) {
647 #if defined(ISP_HW_V32) || defined(ISP_HW_V32_LITE)
648 snprintf(buffer,
649 sizeof(buffer),
650 "frame%08d-gain[%08.5f]-time[%08.5f]-"
651 "awbGain1[%08d_%08d_%08d_%08d]-dgain[%08d]-afcode[%08d_%08d]\n",
652 frame_id,
653 expParams->data()->aecExpInfo.LinearExp.exp_real_params.analog_gain,
654 expParams->data()->aecExpInfo.LinearExp.exp_real_params.integration_time,
655 ispParams.awb_gain_cfg.awb1_gain_r,
656 ispParams.awb_gain_cfg.awb1_gain_gr,
657 ispParams.awb_gain_cfg.awb1_gain_gb,
658 ispParams.awb_gain_cfg.awb1_gain_b,
659 1,
660 focusCode,
661 zoomCode);
662
663 #endif
664 }
665 }
666 }
667 }
668
669 fwrite((void *)buffer, strlen(buffer), 1, fp);
670 fflush(fp);
671 fclose(fp);
672 }
673 }
674
calculate_stride_per_line(const struct capture_fmt & fmt,uint32_t & bytesPerLine,SmartPtr<V4l2Device> dev)675 int CaptureRawData::calculate_stride_per_line(const struct capture_fmt& fmt,
676 uint32_t& bytesPerLine, SmartPtr<V4l2Device> dev)
677 {
678 uint32_t pixelsPerLine = 0, stridePerLine = 0;
679 /* The actual size stored in the memory */
680 uint32_t actualBytesPerLine = 0;
681
682 bytesPerLine = sns_width * fmt.bpp[0] / 8;
683
684 pixelsPerLine = fmt.pcpp * DIV_ROUND_UP(sns_width, fmt.pcpp);
685 actualBytesPerLine = pixelsPerLine * fmt.bpp[0] / 8;
686
687 #if 0
688 /* mipi wc(Word count) must be 4 byte aligned */
689 stridePerLine = 256 * DIV_ROUND_UP(actualBytesPerLine, 256);
690 #else
691 struct v4l2_format format;
692 memset(&format, 0, sizeof(format));
693
694 dev->get_format(format);
695 stridePerLine = format.fmt.pix_mp.plane_fmt[0].bytesperline;
696 #endif
697
698 LOGD_CAMHW_SUBM(CAPTURERAW_SUBM, "sns_width: %d, pixelsPerLine: %d, bytesPerLine: %d, stridePerLine: %d\n",
699 sns_width,
700 pixelsPerLine,
701 bytesPerLine,
702 stridePerLine);
703
704 return stridePerLine;
705 }
706
707 /*
708 * Refer to "Raw file structure" in the header of this file
709 */
710 XCamReturn
write_frame_header_to_raw(FILE * fp,int dev_index,int sequence,int working_mode,SmartPtr<V4l2Device> dev)711 CaptureRawData::write_frame_header_to_raw(FILE *fp, int dev_index,
712 int sequence, int working_mode, SmartPtr<V4l2Device> dev)
713 {
714 uint8_t buffer[128] = {0};
715 uint32_t stridePerLine = 0, bytesPerLine = 0;
716 const struct capture_fmt* fmt = nullptr;
717 uint8_t mode = 0;
718 uint8_t frame_type = 0, storage_type = 0;
719
720 if (fp == nullptr)
721 return XCAM_RETURN_ERROR_PARAM;
722
723 if ((fmt = find_fmt(pixelformat)))
724 stridePerLine = calculate_stride_per_line(*fmt, bytesPerLine, dev);
725
726 if (working_mode == RK_AIQ_ISP_HDR_MODE_3_FRAME_HDR || \
727 working_mode == RK_AIQ_ISP_HDR_MODE_3_LINE_HDR) {
728 mode = 3;
729 frame_type = dev_index == 0 ? 1 : dev_index == 1 ? 2 : 3;
730 } else if (working_mode == RK_AIQ_ISP_HDR_MODE_2_FRAME_HDR || \
731 working_mode == RK_AIQ_ISP_HDR_MODE_2_LINE_HDR) {
732 mode = 2;
733 frame_type = dev_index == 0 ? 1 : 3;
734 } else {
735 mode = 1;
736 }
737
738 _stride_perline = stridePerLine;
739
740 *((uint16_t* )buffer) = RAW_FILE_IDENT; // Identifier
741 *((uint16_t* )(buffer + 2)) = HEADER_LEN; // Header length
742 *((uint32_t* )(buffer + 4)) = sequence; // Frame number
743 *((uint16_t* )(buffer + 8)) = sns_width; // Image width
744 *((uint16_t* )(buffer + 10)) = sns_height; // Image height
745 *(buffer + 12) = fmt->bpp[0]; // Bit depth
746 *(buffer + 13) = fmt->bayer_fmt; // Bayer format
747 *(buffer + 14) = mode; // Number of HDR frame
748 *(buffer + 15) = frame_type; // Current frame type
749 *(buffer + 16) = storage_type; // Storage type
750 *((uint16_t* )(buffer + 17)) = stridePerLine; // Line stride
751 *((uint16_t* )(buffer + 19)) = bytesPerLine; // Effective line stride
752
753 fwrite(buffer, sizeof(buffer), 1, fp);
754 fflush(fp);
755
756 LOGV_CAMHW_SUBM(CAPTURERAW_SUBM, "frame%d: image rect: %dx%d, %d bit depth, Bayer fmt: %d, "
757 "hdr frame number: %d, frame type: %d, Storage type: %d, "
758 "line stride: %d, Effective line stride: %d\n",
759 sequence, sns_width, sns_height,
760 fmt->bpp[0], fmt->bayer_fmt, mode,
761 frame_type, storage_type, stridePerLine,
762 bytesPerLine);
763
764 return XCAM_RETURN_NO_ERROR;
765 }
766
767 XCamReturn
write_raw_to_file(FILE * fp,int dev_index,int sequence,void * userptr,int size)768 CaptureRawData::write_raw_to_file(FILE* fp, int dev_index,
769 int sequence, void* userptr, int size)
770 {
771 if (fp == nullptr)
772 return XCAM_RETURN_ERROR_PARAM;
773
774 fwrite(userptr, size, 1, fp);
775 fflush(fp);
776
777 if (!dev_index) {
778 for (int i = 0; i < _capture_raw_num; i++)
779 printf(">");
780 printf("\n");
781
782 }
783
784 LOGV_CAMHW_SUBM(CAPTURERAW_SUBM, "dev(%d) write frame%d raw\n", dev_index, sequence);
785 return XCAM_RETURN_NO_ERROR;
786 }
787
788 void
write_reg_to_file(uint32_t base_addr,uint32_t offset_addr,int len,int sequence)789 CaptureRawData::write_reg_to_file(uint32_t base_addr, uint32_t offset_addr,
790 int len, int sequence)
791 {
792
793 }
794
795 XCamReturn
creat_raw_dir(const char * path)796 CaptureRawData::creat_raw_dir(const char* path)
797 {
798 time_t now;
799 struct tm* timenow;
800 struct timeval tv;
801 struct timezone tz;
802
803 if (!path)
804 return XCAM_RETURN_ERROR_FAILED;
805
806 gettimeofday(&tv, &tz);
807 time(&now);
808 timenow = localtime(&now);
809
810 if (access(path, W_OK) == -1) {
811 if (mkdir(path, 0755) < 0) {
812 LOGE_CAMHW_SUBM(CAPTURERAW_SUBM, "mkdir %s error(%s)!\n",
813 path, strerror(errno));
814 return XCAM_RETURN_ERROR_FILE;
815 }
816 }
817
818 snprintf(raw_dir_path, sizeof(raw_dir_path), "%s/Cam%d-raw_%04d-%02d-%02d_%02d-%02d-%02d-%03ld",
819 path,
820 _camId,
821 timenow->tm_year + 1900,
822 timenow->tm_mon + 1,
823 timenow->tm_mday,
824 timenow->tm_hour,
825 timenow->tm_min,
826 timenow->tm_sec,
827 tv.tv_usec/1000);
828
829 LOGV_CAMHW_SUBM(CAPTURERAW_SUBM, "mkdir %s for capturing %d frames raw!\n",
830 raw_dir_path, _capture_raw_num);
831
832 if(mkdir(raw_dir_path, 0755) < 0) {
833 LOGE_CAMHW_SUBM(CAPTURERAW_SUBM, "mkdir %s error(%s)!!!\n",
834 raw_dir_path, strerror(errno));
835 return XCAM_RETURN_ERROR_PARAM;
836 }
837
838 _is_raw_dir_exist = true;
839
840 return XCAM_RETURN_ERROR_PARAM;
841 }
842
843 XCamReturn
notify_capture_raw()844 CaptureRawData::notify_capture_raw()
845 {
846 SmartLock locker(_capture_image_mutex);
847 _capture_image_cond.broadcast();
848
849 return XCAM_RETURN_NO_ERROR;
850 }
851
852 XCamReturn
capture_raw_ctl(capture_raw_t type,int count,const char * capture_dir,char * output_dir)853 CaptureRawData::capture_raw_ctl(capture_raw_t type, int count, const char* capture_dir, char* output_dir)
854 {
855 XCamReturn ret = XCAM_RETURN_NO_ERROR;
856
857 _capture_raw_type = type;
858 if (_capture_raw_type == CAPTURE_RAW_SYNC) {
859 if (capture_dir != nullptr)
860 snprintf(user_set_raw_dir, sizeof( user_set_raw_dir),
861 "%s/capture_image", capture_dir);
862 else
863 strcpy(user_set_raw_dir, DEFAULT_CAPTURE_RAW_PATH);
864
865 char cmd_buffer[32] = {0};
866 snprintf(cmd_buffer, sizeof(cmd_buffer),
867 "echo %d > %s_c%d",
868 count, CAPTURE_CNT_FILENAME, _camId);
869 system(cmd_buffer);
870
871 _capture_image_mutex.lock();
872 if (_capture_image_cond.timedwait(_capture_image_mutex, 30000000) != 0)
873 ret = XCAM_RETURN_ERROR_TIMEOUT;
874 else {
875 // TODO(FIX ME): mistaken use of strncpy.
876 strcpy(output_dir, raw_dir_path);
877 }
878 _capture_image_mutex.unlock();
879 } else if (_capture_raw_type == CAPTURE_RAW_AND_YUV_SYNC) {
880 LOGD_CAMHW_SUBM(CAPTURERAW_SUBM, "capture raw and yuv images simultaneously!");
881 }
882
883 return ret;
884 }
885
save_metadata_and_register(uint32_t frameId,rkisp_effect_params_v20 & ispParams,SmartPtr<RkAiqSensorExpParamsProxy> & expParams,SmartPtr<RkAiqAfInfoProxy> & afParams,int working_mode)886 void CaptureRawData::save_metadata_and_register
887 (
888 uint32_t frameId,
889 rkisp_effect_params_v20& ispParams,
890 SmartPtr<RkAiqSensorExpParamsProxy>& expParams,
891 SmartPtr<RkAiqAfInfoProxy>& afParams,
892 int working_mode
893 )
894 {
895 if (_capture_metadata_num > 0) {
896 char file_name[32] = {0};
897 int capture_cnt = 0;
898 uint32_t rawFrmId = 0;
899
900 snprintf(file_name, sizeof(file_name), "%s", CAPTURE_CNT_FILENAME);
901 bool ret = get_value_from_file(file_name, capture_cnt, rawFrmId);
902 if (!ret) {
903 // test multi cam mode
904 snprintf(file_name, sizeof(file_name), "%.50s_c%d", CAPTURE_CNT_FILENAME, _camId);
905 get_value_from_file(file_name, capture_cnt, rawFrmId);
906 }
907 LOGD_CAMHW_SUBM(CAPTURERAW_SUBM, "rawFrmId: %d, sequence: %d, _capture_metadata_num: %d\n",
908 rawFrmId, frameId,
909 _capture_metadata_num);
910 if (_is_raw_dir_exist && frameId >= rawFrmId && expParams.ptr()) {
911 #ifdef WRITE_ISP_REG
912 write_reg_to_file(ISP_REGS_BASE, 0x0, 0x6000, frameId);
913 #endif
914 #ifdef WRITE_ISPP_REG
915 write_reg_to_file(ISPP_REGS_BASE, 0x0, 0xc94, frameId);
916 #endif
917 write_metadata_to_file(raw_dir_path,
918 frameId,
919 ispParams, expParams, afParams,working_mode);
920
921 _capture_metadata_num--;
922 if (!_capture_metadata_num) {
923 _is_raw_dir_exist = false;
924 if (_capture_raw_type == CAPTURE_RAW_SYNC) {
925 _capture_image_mutex.lock();
926 _capture_image_cond.broadcast();
927 _capture_image_mutex.unlock();
928 }
929
930 LOGD_CAMHW_SUBM(CAPTURERAW_SUBM, "stop capturing raw!\n");
931 }
932 }
933 }
934 }
935
936 } //namspace RkCam
937