xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rkisp_demo/demo/rkisp_demo.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * V4L2 video capture example
3  * AUTHOT : Jacob Chen
4  * DATA : 2018-02-25
5  */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <assert.h>
10 #include <getopt.h> /* getopt_long() */
11 #include <fcntl.h> /* low-level i/o */
12 #include <unistd.h>
13 #include <errno.h>
14 #include <sys/stat.h>
15 #include <sys/types.h>
16 #include <sys/time.h>
17 #include <sys/mman.h>
18 #include <sys/ioctl.h>
19 #include <dlfcn.h>
20 #include <signal.h>
21 #include <dirent.h>
22 #if ISPDEMO_ENABLE_DRM
23 #include "drmDsp.h"
24 #endif
25 #include "uAPI2/rk_aiq_user_api2_sysctl.h"
26 #include "rk_aiq_user_api2_debug.h"
27 #include "sample_image_process.h"
28 #include "rkisp_demo.h"
29 #include <termios.h>
30 
31 
32 #include "ae_algo_demo/third_party_ae_algo.h"
33 //#include "awb_algo_demo/third_party_awb_algo.h"  //for rk3588
34 #include "awb_algo_demo/third_party_awbV32_algo.h" //for rv1106
35 #include "af_algo_demo/third_party_af_algo.h"
36 
37 #if ISPDEMO_ENABLE_RGA && ISPDEMO_ENABLE_DRM
38 #include "display.h"
39 #include "rga.h"
40 #endif
41 #include <list>
42 #include <vector>
43 #include <string>
44 #include <algorithm>
45 
46 #define CLEAR(x) memset(&(x), 0, sizeof(x))
47 #define FMT_NUM_PLANES 1
48 
49 #define BUFFER_COUNT 3
50 
51 #ifdef ANDROID
52 #define CAPTURE_RAW_PATH "/data"
53 #define DEFAULT_CAPTURE_RAW_PATH "/data/capture_image"
54 #else
55 #define CAPTURE_RAW_PATH "/tmp"
56 #define DEFAULT_CAPTURE_RAW_PATH "/tmp/capture_image"
57 #endif
58 #define CAPTURE_CNT_FILENAME ".capture_cnt"
59 // #define ENABLE_UAPI_TEST
60 #define IQFILE_PATH_MAX_LEN 256
61 // #define CUSTOM_AE_DEMO_TEST
62 // #define CUSTOM_GROUP_AE_DEMO_TEST
63 //#define CUSTOM_AWB_DEMO_TEST
64 // #define TEST_MEMS_SENSOR_INTF
65 // #define CUSTOM_AF_DEMO_TEST
66 // #define CUSTOM_GROUP_AWB_DEMO_TEST
67 #ifdef ISPFEC_API
68 #include "IspFec/rk_ispfec_api.h"
69 #include <xf86drm.h>
70 #include <xf86drmMode.h>
71 #include <libdrm/drm_mode.h>
72 #include <drm_fourcc.h>
73 
74 struct drm_buf {
75   int fb_id;
76   uint32_t handle;
77   uint32_t size;
78   uint32_t pitch;
79   char *map;
80   int dmabuf_fd;
81 };
82 
83 static rk_ispfec_ctx_t* g_ispfec_ctx = NULL;
84 static rk_ispfec_cfg_t g_ispfec_cfg;
85 struct drm_buf g_drm_buf_pic_out;
86 struct drm_buf g_drm_buf_xint;
87 struct drm_buf g_drm_buf_xfra;
88 struct drm_buf g_drm_buf_yint;
89 struct drm_buf g_drm_buf_yfra;
90 #endif
91 
92 struct buffer {
93     void *start;
94     size_t length;
95     int export_fd;
96     int sequence;
97 };
98 
99 enum TEST_CTL_TYPE {
100     TEST_CTL_TYPE_DEFAULT,
101     TEST_CTL_TYPE_REPEAT_INIT_PREPARE_START_STOP_DEINIT,
102     TEST_CTL_TYPE_REPEAT_START_STOP,
103     TEST_CTL_TYPE_REPEAT_PREPARE_START_STOP,
104 };
105 
106 static struct termios oldt;
107 static int silent;
108 static demo_context_t *g_main_ctx = NULL,  *g_second_ctx = NULL, *g_third_ctx = NULL, *g_fourth_ctx = NULL;
109 static bool _if_quit = false;
110 
111 #ifdef ISPFEC_API
alloc_drm_buffer(int fd,int width,int height,int bpp,struct drm_buf * buf)112 int alloc_drm_buffer(int fd, int width, int height,
113 		int bpp, struct drm_buf *buf)
114 {
115 	struct drm_mode_create_dumb alloc_arg;
116 	struct drm_mode_map_dumb mmap_arg;
117 	struct drm_mode_destroy_dumb destory_arg;
118 	void *map;
119 	int ret;
120 
121 	memset(&alloc_arg, 0, sizeof(alloc_arg));
122 	alloc_arg.bpp = bpp;
123 	alloc_arg.width = width;
124 	alloc_arg.height = height;
125 
126 	ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &alloc_arg);
127 	if (ret) {
128 		printf("failed to create dumb buffer\n");
129 		return ret;
130 	}
131 
132 	memset(&mmap_arg, 0, sizeof(mmap_arg));
133 	mmap_arg.handle = alloc_arg.handle;
134 	ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mmap_arg);
135 	if (ret) {
136 		printf("failed to create map dumb\n");
137 		ret = -EINVAL;
138 		goto destory_dumb;
139 	}
140 	map = mmap(0, alloc_arg.size,
141 		PROT_READ | PROT_WRITE, MAP_SHARED,
142 		fd, mmap_arg.offset);
143 	if (map == MAP_FAILED) {
144 		printf("failed to mmap buffer\n");
145 		ret = -EINVAL;
146 		goto destory_dumb;
147 	}
148 	ret = drmPrimeHandleToFD(fd, alloc_arg.handle, 0,
149 			&buf->dmabuf_fd);
150 	if (ret) {
151 		printf("failed to get dmabuf fd\n");
152 		munmap(map, alloc_arg.size);
153 		ret = -EINVAL;
154 		goto destory_dumb;
155 	}
156 	buf->size = alloc_arg.size;
157 	buf->map = (char*)map;
158 
159 destory_dumb:
160 	memset(&destory_arg, 0, sizeof(destory_arg));
161 	destory_arg.handle = alloc_arg.handle;
162 	drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destory_arg);
163 	return ret;
164 }
165 
free_drm_buffer(int fd,struct drm_buf * buf)166 int free_drm_buffer(int fd, struct drm_buf *buf)
167 {
168 	if (buf) {
169 		close(buf->dmabuf_fd);
170 		return munmap(buf->map, buf->size);
171 	}
172 	return -EINVAL;
173 }
174 
init_ispfec_bufs(rk_ispfec_cfg_t * cfg)175 int init_ispfec_bufs(rk_ispfec_cfg_t* cfg)
176 {
177     int ret = 0;
178 	int drm_fd = drmOpen("rockchip", NULL);
179 	if (drm_fd < 0) {
180 		printf("failed to open rockchip drm\n");
181         return -1;
182 	}
183 
184     int mesh_size = rk_ispfec_api_calFecMeshsize(cfg->in_width, cfg->in_height);
185 
186 	printf("\nmesh_size:%d\n", mesh_size);
187 	ret = alloc_drm_buffer(drm_fd, mesh_size * 2, 1, 8, &g_drm_buf_xint);
188 	if (ret)
189 		goto close_drm_fd;
190 	printf("xint fd:%d size:%d\n", g_drm_buf_xint.dmabuf_fd, g_drm_buf_xint.size);
191 
192 	ret = alloc_drm_buffer(drm_fd, mesh_size, 1, 8, &g_drm_buf_xfra);
193 	if (ret)
194 		goto free_drm_buf_xint;
195 	printf("xfra fd:%d size:%d\n", g_drm_buf_xfra.dmabuf_fd, g_drm_buf_xfra.size);
196 
197 	ret = alloc_drm_buffer(drm_fd, mesh_size * 2, 1, 8, &g_drm_buf_yint);
198 	if (ret)
199 		goto free_drm_buf_xfra;
200 	printf("yint fd:%d size:%d\n", g_drm_buf_yint.dmabuf_fd, g_drm_buf_yint.size);
201 
202 	ret = alloc_drm_buffer(drm_fd, mesh_size, 1, 8, &g_drm_buf_yfra);
203 	if (ret)
204 		goto free_drm_buf_yint;
205 	printf("yfra fd:%d size:%d\n", g_drm_buf_yfra.dmabuf_fd, g_drm_buf_yfra.size);
206 
207 	ret = alloc_drm_buffer(drm_fd, cfg->out_width, cfg->out_height * 3 / 2, 8, &g_drm_buf_pic_out);
208 	if (ret)
209 		goto free_drm_buf_yfra;
210 	printf("out pic fd:%d size:%d\n", g_drm_buf_pic_out.dmabuf_fd, g_drm_buf_pic_out.size);
211 
212     cfg->mesh_xint.dmaFd = g_drm_buf_xint.dmabuf_fd;
213     cfg->mesh_xint.size = g_drm_buf_xint.size;
214     cfg->mesh_xint.vir_addr = g_drm_buf_xint.map;
215 
216     cfg->mesh_xfra.dmaFd = g_drm_buf_xfra.dmabuf_fd;
217     cfg->mesh_xfra.size = g_drm_buf_xfra.size;
218     cfg->mesh_xfra.vir_addr = g_drm_buf_xfra.map;
219 
220     cfg->mesh_yint.dmaFd = g_drm_buf_yint.dmabuf_fd;
221     cfg->mesh_yint.size = g_drm_buf_yint.size;
222     cfg->mesh_yint.vir_addr = g_drm_buf_yint.map;
223 
224     cfg->mesh_yfra.dmaFd = g_drm_buf_yfra.dmabuf_fd;
225     cfg->mesh_yfra.size = g_drm_buf_yfra.size;
226     cfg->mesh_yfra.vir_addr = g_drm_buf_yfra.map;
227 
228     goto close_drm_fd;
229 
230 free_drm_buf_pic_out:
231 	free_drm_buffer(drm_fd, &g_drm_buf_pic_out);
232 free_drm_buf_yfra:
233 	free_drm_buffer(drm_fd, &g_drm_buf_yfra);
234 free_drm_buf_yint:
235 	free_drm_buffer(drm_fd, &g_drm_buf_yfra);
236 free_drm_buf_xfra:
237 	free_drm_buffer(drm_fd, &g_drm_buf_xfra);
238 free_drm_buf_xint:
239 	free_drm_buffer(drm_fd, &g_drm_buf_xint);
240 close_drm_fd:
241 	close(drm_fd);
242 
243     return ret;
244 }
245 
deinit_ispfec_bufs()246 void deinit_ispfec_bufs()
247 {
248 	free_drm_buffer(-1, &g_drm_buf_pic_out);
249 	free_drm_buffer(-1, &g_drm_buf_yfra);
250 	free_drm_buffer(-1, &g_drm_buf_yfra);
251 	free_drm_buffer(-1, &g_drm_buf_xfra);
252 	free_drm_buffer(-1, &g_drm_buf_xint);
253 }
254 #endif
255 
256 //restore terminal settings
restore_terminal_settings(void)257 void restore_terminal_settings(void)
258 {
259     // Apply saved settings
260     tcsetattr(0, TCSANOW, &oldt);
261 }
262 
263 //make terminal read 1 char at a time
disable_terminal_return(void)264 void disable_terminal_return(void)
265 {
266     struct termios newt;
267 
268     //save terminal settings
269     tcgetattr(0, &oldt);
270     //init new settings
271     newt = oldt;
272     //change settings
273     newt.c_lflag &= ~(ICANON | ECHO);
274     //apply settings
275     tcsetattr(0, TCSANOW, &newt);
276 
277     //make sure settings will be restored when program ends
278     atexit(restore_terminal_settings);
279 }
280 
get_dev_name(demo_context_t * ctx)281 char* get_dev_name(demo_context_t* ctx)
282 {
283     if (ctx->dev_using == 1)
284         return ctx->dev_name;
285     else if (ctx->dev_using == 2)
286         return ctx->dev_name2;
287     else if (ctx->dev_using == 3)
288         return ctx->dev_name3;
289     else if (ctx->dev_using == 4)
290         return ctx->dev_name4;
291     else {
292         ERR("!!!dev_using is not supported!!!");
293         return NULL;
294     }
295 }
296 
get_sensor_name(demo_context_t * ctx)297 char* get_sensor_name(demo_context_t* ctx)
298 {
299     return ctx->sns_name;
300 }
301 
test_update_iqfile(const demo_context_t * demo_ctx)302 void test_update_iqfile(const demo_context_t* demo_ctx)
303 {
304     char iqfile[IQFILE_PATH_MAX_LEN] = {0};
305 
306     printf("\nspecial an new iqfile:\n");
307     strcat(iqfile, demo_ctx->iqpath);
308     strcat(iqfile, "/");
309     char* ret = fgets(iqfile + strlen(iqfile), IQFILE_PATH_MAX_LEN, stdin);
310 
311     char* json = strstr(iqfile, "json");
312 
313     if (!json) {
314         printf("[AIQ]input is not an valide json:%s\n", iqfile);
315         return;
316     }
317 
318     /* fgets may add '\n' in the end of input, delete it */
319     json += strlen("json");
320     *json = '\0';
321 
322     printf("[AIQ] appling new iq file:%s\n", iqfile);
323 
324     rk_aiq_uapi2_sysctl_updateIq(demo_ctx->aiq_ctx, iqfile);
325 }
326 
327 #if 0
328 static int set_ae_onoff(const rk_aiq_sys_ctx_t* ctx, bool onoff);
329 void test_imgproc(const demo_context_t* demo_ctx) {
330 
331     if (demo_ctx == NULL) {
332         return;
333     }
334 
335     const rk_aiq_sys_ctx_t* ctx = (const rk_aiq_sys_ctx_t*)(demo_ctx->aiq_ctx);
336 
337     /*TODO: when rkaiq_3A_server & rkisp_demo run in two different shell, rk_aiq_sys_ctx_t would be null?*/
338     if (ctx == NULL) {
339         printf("ERROR : rk_aiq_sys_ctx_t is null.\n");
340         _if_quit = true;
341         return;
342     }
343 
344     int key = getchar();
345     printf("press key=[%c]\n", key);
346 
347     opMode_t mode;
348     paRange_t range;
349     expPwrLineFreq_t freq;
350     rk_aiq_wb_scene_t scene;
351     rk_aiq_wb_gain_t gain;
352     rk_aiq_wb_cct_t ct;
353     antiFlickerMode_t flicker;
354     switch (key)
355     {
356     case '0':
357         rk_aiq_uapi_setExpMode(ctx, OP_MANUAL);
358         printf("set exp manual\n");
359         break;
360     case '.':
361         rk_aiq_uapi_setExpMode(ctx, OP_AUTO);
362         printf("set exp auto\n");
363         break;
364     case '1':
365         rk_aiq_uapi_getExpMode(ctx, &mode);
366         printf("exp mode=%d\n", mode);
367         break;
368     case '2':
369         range.min = 5.0f;
370         range.max = 8.0f;
371         rk_aiq_uapi_setExpGainRange(ctx, &range);
372         printf("set gain range\n");
373         break;
374     case '3':
375         rk_aiq_uapi_getExpGainRange(ctx, &range);
376         printf("get gain range[%f,%f]\n", range.min, range.max);
377         break;
378     case '4':
379         range.min = 10.0f;
380         range.max = 30.0f;
381         rk_aiq_uapi_setExpTimeRange(ctx, &range);
382         printf("set time range\n");
383         break;
384     case '5':
385         rk_aiq_uapi_getExpTimeRange(ctx, &range);
386         printf("get time range[%f,%f]\n", range.min, range.max);
387         break;
388     case '6':
389         rk_aiq_uapi_setExpPwrLineFreqMode(ctx, EXP_PWR_LINE_FREQ_50HZ);
390         printf("setExpPwrLineFreqMode 50hz\n");
391         break;
392     case ',':
393         rk_aiq_uapi_setExpPwrLineFreqMode(ctx, EXP_PWR_LINE_FREQ_60HZ);
394         printf("setExpPwrLineFreqMode 60hz\n");
395         break;
396     case '7':
397         rk_aiq_uapi_getExpPwrLineFreqMode(ctx, &freq);
398         printf("getExpPwrLineFreqMode=%d\n", freq);
399         break;
400     case '8':
401         rk_aiq_uapi_setWBMode(ctx, OP_MANUAL);
402         printf("setWBMode manual\n");
403         break;
404     case '/':
405         rk_aiq_uapi_setWBMode(ctx, OP_AUTO);
406         printf("setWBMode auto\n");
407         break;
408     case '9':
409         rk_aiq_uapi_getWBMode(ctx, &mode);
410         printf("getWBMode=%d\n", mode);
411         break;
412     case 'a':
413         rk_aiq_uapi_lockAWB(ctx);
414         printf("lockAWB\n");
415         break;
416     case 'b':
417         rk_aiq_uapi_unlockAWB(ctx);
418         printf("unlockAWB\n");
419         break;
420     case 'c':
421         rk_aiq_uapi_setMWBScene(ctx, RK_AIQ_WBCT_TWILIGHT);
422         printf("setMWBScene\n");
423         break;
424     case 'd':
425         rk_aiq_uapi_getMWBScene(ctx, &scene);
426         printf("getMWBScene=%d\n", scene);
427         break;
428     case 'e':
429         gain.rgain = 0.5f;
430         gain.grgain = 0.5f;
431         gain.gbgain = 0.5f;
432         gain.bgain = 0.5f;
433         rk_aiq_uapi_setMWBGain(ctx, &gain);
434         printf("setMWBGain\n");
435         break;
436     case 'f':
437         rk_aiq_uapi_getMWBGain(ctx, &gain);
438         printf("getMWBGain=[%f %f %f %f]\n", gain.rgain, gain.grgain, gain.gbgain, gain.bgain);
439         break;
440     case 'g':
441         break;
442     case 'h':
443         break;
444     case 'i':
445         rk_aiq_uapi_setAntiFlickerMode(ctx, ANTIFLICKER_NORMAL_MODE);
446         printf("setAntiFlickerMode normal\n");
447         break;
448     case 'j':
449         rk_aiq_uapi_setAntiFlickerMode(ctx, ANTIFLICKER_AUTO_MODE);
450         printf("setAntiFlickerMode auto\n");
451         break;
452     case 'k':
453         rk_aiq_uapi_getAntiFlickerMode(ctx, &flicker);
454         printf("getAntiFlickerMode=%d\n", flicker);
455         break;
456     case 'l':
457         rk_aiq_uapi_setSaturation(ctx, 50);
458         printf("setSaturation\n");
459         break;
460     case 'm':
461         unsigned int level1;
462         rk_aiq_uapi_getSaturation(ctx, &level1);
463         printf("getSaturation=%d\n", level1);
464         break;
465     case 'n':
466         rk_aiq_uapi_setCrSuppsn(ctx, 50);
467         printf("setCrSuppsn\n");
468         break;
469     case 'o':
470         unsigned int level2;
471         rk_aiq_uapi_getCrSuppsn(ctx, &level2);
472         printf("getCrSuppsn=%d\n", level2);
473         break;
474     case 'p':
475         //rk_aiq_uapi_setHDRMode(ctx, OP_AUTO);
476         printf("setHDRMode\n");
477         break;
478     case 'q':
479         //rk_aiq_uapi_setHDRMode(ctx, OP_MANUAL);
480         printf("setHDRMode\n");
481         break;
482     case 'r':
483         //rk_aiq_uapi_getHDRMode(ctx, &mode);
484         printf("getHDRMode=%d\n", mode);
485         break;
486     case 's': {
487         unsigned int set_anr_strength = 80;
488         unsigned int get_anr_strength = 0;
489         rk_aiq_uapi_setANRStrth(ctx, set_anr_strength);
490         printf("setANRStrth %u \n", set_anr_strength);
491         sleep(1);
492         rk_aiq_uapi_getANRStrth(ctx, &get_anr_strength);
493         printf("getANRStrth %u \n", get_anr_strength);
494         break;
495     }
496     case 't': {
497         unsigned int set_strength = 80;
498         unsigned int get_space_strength = 0;
499         unsigned int get_mfnr_strength = 0;
500         bool state;
501         rk_aiq_uapi_setMSpaNRStrth(ctx, true, set_strength);
502         rk_aiq_uapi_setMTNRStrth(ctx, true, set_strength);
503         printf("setMSpaNRStrth and setMTNRStrth :%u \n", set_strength);
504         rk_aiq_uapi_getMSpaNRStrth(ctx, &state, &get_space_strength);
505         rk_aiq_uapi_getMTNRStrth(ctx, &state, &get_mfnr_strength);
506         printf("setMSpaNRStrth and setMTNRStrth :%u %u\n", get_space_strength, get_mfnr_strength);
507         break;
508     }
509     case 'u':
510         //rk_aiq_uapi_setDhzMode(ctx, OP_MANUAL);
511         //printf("setDhzMode\n");
512         break;
513     case 'v':
514         //rk_aiq_uapi_getDhzMode(ctx, &mode);
515         // printf("getDhzMode=%d\n", mode);
516         break;
517     case 'w':
518     {
519         bool stat = false;
520         //unsigned int level4 = 0;
521         //rk_aiq_uapi_getMHDRStrth(ctx, &stat, &level4);
522         //printf("getMHDRStrth: status:%d, level=%d\n", stat, level4);
523     }
524     break;
525     case 'x':
526         //rk_aiq_uapi_setMHDRStrth(ctx, true, 8);
527         //printf("setMHDRStrth true\n");
528         break;
529     case 'y':
530     {
531         bool mod_en;
532         rk_aiq_uapi2_sysctl_getModuleCtl(ctx, RK_MODULE_TNR, &mod_en);
533         printf("getModuleCtl=%d\n", mod_en);
534         if (mod_en) {
535             rk_aiq_uapi2_sysctl_setModuleCtl(ctx, RK_MODULE_TNR, false);
536         } else {
537             rk_aiq_uapi2_sysctl_setModuleCtl(ctx, RK_MODULE_TNR, true);
538         }
539     }
540     break;
541     case 'z':
542         rk_aiq_uapi_setFocusMode(ctx, OP_AUTO);
543         printf("setFocusMode OP_AUTO\n");
544         break;
545     case 'A':
546         rk_aiq_uapi_setFocusMode(ctx, OP_SEMI_AUTO);
547         printf("setFocusMode OP_SEMI_AUTO\n");
548         break;
549     case 'B':
550         rk_aiq_uapi_setFocusMode(ctx, OP_MANUAL);
551         printf("setFocusMode OP_MANUAL\n");
552         break;
553     case 'C':
554         rk_aiq_uapi_manualTrigerFocus(ctx);
555         printf("manualTrigerFocus\n");
556         break;
557     case 'D': {
558         rk_aiq_af_zoomrange range;
559         int code;
560 
561         rk_aiq_uapi_getZoomRange(ctx, &range);
562         printf("zoom.min_pos %d, zoom.max_pos %d\n", range.min_pos, range.max_pos);
563 
564         rk_aiq_uapi_getOpZoomPosition(ctx, &code);
565         printf("getOpZoomPosition code %d\n", code);
566 
567         code += 20;
568         if (code > range.max_pos)
569             code = range.max_pos;
570         rk_aiq_uapi_setOpZoomPosition(ctx, code);
571         rk_aiq_uapi_endOpZoomChange(ctx);
572         printf("setOpZoomPosition %d\n", code);
573     }
574     break;
575     case 'E': {
576         rk_aiq_af_zoomrange range;
577         int code;
578 
579         rk_aiq_uapi_getZoomRange(ctx, &range);
580         printf("zoom.min_pos %d, zoom.max_pos %d\n", range.min_pos, range.max_pos);
581 
582         rk_aiq_uapi_getOpZoomPosition(ctx, &code);
583         printf("getOpZoomPosition code %d\n", code);
584 
585         code -= 20;
586         if (code < range.min_pos)
587             code = range.min_pos;
588         rk_aiq_uapi_setOpZoomPosition(ctx, code);
589         rk_aiq_uapi_endOpZoomChange(ctx);
590         printf("setOpZoomPosition %d\n", code);
591     }
592     break;
593     case 'F': {
594         rk_aiq_af_focusrange range;
595         short code;
596 
597         rk_aiq_uapi_getFocusRange(ctx, &range);
598         printf("focus.min_pos %d, focus.max_pos %d\n", range.min_pos, range.max_pos);
599 
600         rk_aiq_uapi_getFixedModeCode(ctx, &code);
601 
602         code++;
603         if (code > range.max_pos)
604             code = range.max_pos;
605         rk_aiq_uapi_setFixedModeCode(ctx, code);
606         printf("setFixedModeCode %d\n", code);
607     }
608     break;
609     case 'G': {
610         rk_aiq_af_focusrange range;
611         short code;
612 
613         rk_aiq_uapi_getFocusRange(ctx, &range);
614         printf("focus.min_pos %d, focus.max_pos %d\n", range.min_pos, range.max_pos);
615 
616         rk_aiq_uapi_getFixedModeCode(ctx, &code);
617 
618         code--;
619         if (code < range.min_pos)
620             code = range.min_pos;
621         rk_aiq_uapi_setFixedModeCode(ctx, code);
622         printf("setFixedModeCode %d\n", code);
623     }
624     break;
625     case 'H': {
626         rk_aiq_af_attrib_t attr;
627         uint16_t gamma_y[RKAIQ_RAWAF_GAMMA_NUM] =
628         {0, 45, 108, 179, 245, 344, 409, 459, 500, 567, 622, 676, 759, 833, 896, 962, 1023};
629 
630         rk_aiq_user_api_af_GetAttrib(ctx, &attr);
631         attr.manual_meascfg.contrast_af_en = 1;
632         attr.manual_meascfg.rawaf_sel = 0; // normal = 0; hdr = 1
633 
634         attr.manual_meascfg.window_num = 2;
635         attr.manual_meascfg.wina_h_offs = 2;
636         attr.manual_meascfg.wina_v_offs = 2;
637         attr.manual_meascfg.wina_h_size = 2580;
638         attr.manual_meascfg.wina_v_size = 1935;
639 
640         attr.manual_meascfg.winb_h_offs = 500;
641         attr.manual_meascfg.winb_v_offs = 600;
642         attr.manual_meascfg.winb_h_size = 300;
643         attr.manual_meascfg.winb_v_size = 300;
644 
645         attr.manual_meascfg.gamma_flt_en = 1;
646         memcpy(attr.manual_meascfg.gamma_y, gamma_y, RKAIQ_RAWAF_GAMMA_NUM * sizeof(uint16_t));
647 
648         attr.manual_meascfg.gaus_flt_en = 1;
649         attr.manual_meascfg.gaus_h0 = 0x20;
650         attr.manual_meascfg.gaus_h1 = 0x10;
651         attr.manual_meascfg.gaus_h2 = 0x08;
652 
653         attr.manual_meascfg.afm_thres = 4;
654 
655         attr.manual_meascfg.lum_var_shift[0] = 0;
656         attr.manual_meascfg.afm_var_shift[0] = 0;
657         attr.manual_meascfg.lum_var_shift[1] = 4;
658         attr.manual_meascfg.afm_var_shift[1] = 4;
659 
660         attr.manual_meascfg.sp_meas.enable = true;
661         attr.manual_meascfg.sp_meas.ldg_xl = 10;
662         attr.manual_meascfg.sp_meas.ldg_yl = 28;
663         attr.manual_meascfg.sp_meas.ldg_kl = (255 - 28) * 256 / 45;
664         attr.manual_meascfg.sp_meas.ldg_xh = 118;
665         attr.manual_meascfg.sp_meas.ldg_yh = 8;
666         attr.manual_meascfg.sp_meas.ldg_kh = (255 - 8) * 256 / 15;
667         attr.manual_meascfg.sp_meas.highlight_th = 245;
668         attr.manual_meascfg.sp_meas.highlight2_th = 200;
669         rk_aiq_user_api_af_SetAttrib(ctx, &attr);
670     }
671     break;
672     case 'I':
673         if (CHECK_ISP_HW_V20()) {
674             rk_aiq_nr_IQPara_t stNRIQPara;
675             rk_aiq_nr_IQPara_t stGetNRIQPara;
676             stNRIQPara.module_bits = (1 << ANR_MODULE_BAYERNR) | (1 << ANR_MODULE_MFNR) | (1 << ANR_MODULE_UVNR) | (1 << ANR_MODULE_YNR);
677             stGetNRIQPara.module_bits = (1 << ANR_MODULE_BAYERNR) | (1 << ANR_MODULE_MFNR) | (1 << ANR_MODULE_UVNR) | (1 << ANR_MODULE_YNR);
678             rk_aiq_user_api_anr_GetIQPara(ctx, &stNRIQPara);
679             for(int m = 0; m < 3; m++) {
680                 for(int k = 0; k < 2; k++) {
681                     for(int i = 0; i < CALIBDB_NR_SHARP_MAX_ISO_LEVEL; i++ ) {
682                         //bayernr
683                         stNRIQPara.stBayernrPara.mode_cell[m].setting[k].filtPara[i] = 0.1;
684                         stNRIQPara.stBayernrPara.mode_cell[m].setting[k].lamda = 500;
685                         stNRIQPara.stBayernrPara.mode_cell[m].setting[k].fixW[0][i] = 0.1;
686                         stNRIQPara.stBayernrPara.mode_cell[m].setting[k].fixW[1][i] = 0.1;
687                         stNRIQPara.stBayernrPara.mode_cell[m].setting[k].fixW[2][i] = 0.1;
688                         stNRIQPara.stBayernrPara.mode_cell[m].setting[k].fixW[3][i] = 0.1;
689 
690                         //mfnr
691                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_y[0] = 2;
692                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_y[1] = 2;
693                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_y[2] = 2;
694                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_y[3] = 2;
695 
696                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_uv[0] = 2;
697                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_uv[1] = 2;
698                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_uv[2] = 2;
699 
700                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_lo_bfscale[0] = 0.4;
701                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_lo_bfscale[1] = 0.6;
702                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_lo_bfscale[2] = 0.8;
703                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_lo_bfscale[3] = 1.0;
704 
705                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_hi_bfscale[0] = 0.4;
706                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_hi_bfscale[1] = 0.6;
707                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_hi_bfscale[2] = 0.8;
708                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_hi_bfscale[3] = 1.0;
709 
710                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_lo_bfscale[0] = 0.1;
711                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_lo_bfscale[1] = 0.2;
712                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_lo_bfscale[2] = 0.3;
713 
714                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_hi_bfscale[0] = 0.1;
715                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_hi_bfscale[1] = 0.2;
716                         stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_hi_bfscale[2] = 0.3;
717 
718                         //ynr
719                         stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].lo_bfScale[0] = 0.4;
720                         stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].lo_bfScale[1] = 0.6;
721                         stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].lo_bfScale[2] = 0.8;
722                         stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].lo_bfScale[3] = 1.0;
723 
724                         stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_bfScale[0] = 0.4;
725                         stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_bfScale[1] = 0.6;
726                         stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_bfScale[2] = 0.8;
727                         stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_bfScale[3] = 1.0;
728 
729                         stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_denoiseStrength = 1.0;
730 
731                         stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_denoiseWeight[0] = 1.0;
732                         stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_denoiseWeight[1] = 1.0;
733                         stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_denoiseWeight[2] = 1.0;
734                         stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_denoiseWeight[3] = 1.0;
735 
736                         stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].denoise_weight[0] = 1.0;
737                         stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].denoise_weight[1] = 1.0;
738                         stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].denoise_weight[2] = 1.0;
739                         stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].denoise_weight[3] = 1.0;
740 
741                         //uvnr
742                         stNRIQPara.stUvnrPara.mode_cell[m].setting[k].step0_uvgrad_ratio[i] = 100;
743                         stNRIQPara.stUvnrPara.mode_cell[m].setting[k].step1_median_ratio[i] = 0.5;
744                         stNRIQPara.stUvnrPara.mode_cell[m].setting[k].step2_median_ratio[i] = 0.5;
745                         stNRIQPara.stUvnrPara.mode_cell[m].setting[k].step1_bf_sigmaR[i] = 20;
746                         stNRIQPara.stUvnrPara.mode_cell[m].setting[k].step2_bf_sigmaR[i] = 16;
747                         stNRIQPara.stUvnrPara.mode_cell[m].setting[k].step3_bf_sigmaR[i] = 8;
748 
749                     }
750                 }
751             }
752 
753             rk_aiq_user_api_anr_SetIQPara(ctx, &stNRIQPara);
754             sleep(5);
755             //printf all the para
756             rk_aiq_user_api_anr_GetIQPara(ctx, &stGetNRIQPara);
757 
758             for(int m = 0; m < 1; m++) {
759                 for(int k = 0; k < 1; k++) {
760                     for(int i = 0; i < CALIBDB_NR_SHARP_MAX_ISO_LEVEL; i++ ) {
761                         printf("\n\n!!!!!!!!!!set:%d cell:%d !!!!!!!!!!\n", k, i);
762                         printf("oyyf222 bayernr: fiter:%f lamda:%f fixw:%f %f %f %f\n",
763                                stGetNRIQPara.stBayernrPara.mode_cell[m].setting[k].filtPara[i],
764                                stGetNRIQPara.stBayernrPara.mode_cell[m].setting[k].lamda,
765                                stGetNRIQPara.stBayernrPara.mode_cell[m].setting[k].fixW[0][i],
766                                stGetNRIQPara.stBayernrPara.mode_cell[m].setting[k].fixW[1][i],
767                                stGetNRIQPara.stBayernrPara.mode_cell[m].setting[k].fixW[2][i],
768                                stGetNRIQPara.stBayernrPara.mode_cell[m].setting[k].fixW[3][i]);
769 
770                         printf("oyyf222 mfnr: limiy:%f %f %f %f uv: %f %f %f, y_lo:%f %f %f %f y_hi:%f %f %f %f uv_lo:%f %f %f uv_hi:%f %f %f\n",
771                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_y[0],
772                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_y[1],
773                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_y[2],
774                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_y[3],
775                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_uv[0],
776                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_uv[1],
777                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_uv[2],
778                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_lo_bfscale[0],
779                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_lo_bfscale[1],
780                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_lo_bfscale[2],
781                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_lo_bfscale[3],
782                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_hi_bfscale[0],
783                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_hi_bfscale[1],
784                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_hi_bfscale[2],
785                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_hi_bfscale[3],
786                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_lo_bfscale[0],
787                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_lo_bfscale[1],
788                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_lo_bfscale[2],
789                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_hi_bfscale[0],
790                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_hi_bfscale[1],
791                                stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_hi_bfscale[2]);
792 
793                         printf("oyyf222 ynr: lo_bf:%f %f %f %f  lo_do:%f %f %f %f  hi_bf:%f %f %f %f stre:%f hi_do:%f %f %f %f\n",
794                                stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].lo_bfScale[0],
795                                stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].lo_bfScale[1],
796                                stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].lo_bfScale[2],
797                                stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].lo_bfScale[3],
798                                stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].denoise_weight[0],
799                                stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].denoise_weight[1],
800                                stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].denoise_weight[2],
801                                stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].denoise_weight[3],
802                                stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_bfScale[0],
803                                stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_bfScale[1],
804                                stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_bfScale[2],
805                                stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_bfScale[3],
806                                stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_denoiseStrength,
807                                stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_denoiseWeight[0],
808                                stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_denoiseWeight[1],
809                                stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_denoiseWeight[2],
810                                stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_denoiseWeight[3]
811                               );
812 
813                         printf("oyyf222 uvnr: uv:%f  med:%f %f sigmaR:%f %f %f\n",
814                                stGetNRIQPara.stUvnrPara.mode_cell[m].setting[k].step0_uvgrad_ratio[i],
815                                stGetNRIQPara.stUvnrPara.mode_cell[m].setting[k].step1_median_ratio[i],
816                                stGetNRIQPara.stUvnrPara.mode_cell[m].setting[k].step2_median_ratio[i],
817                                stGetNRIQPara.stUvnrPara.mode_cell[m].setting[k].step1_bf_sigmaR[i],
818                                stGetNRIQPara.stUvnrPara.mode_cell[m].setting[k].step2_bf_sigmaR[i],
819                                stGetNRIQPara.stUvnrPara.mode_cell[m].setting[k].step3_bf_sigmaR[i]);
820 
821                         printf("!!!!!!!!!!set:%d cell:%d  end !!!!!!!!!!\n\n", k, i);
822                     }
823                 }
824             }
825         }
826         break;
827     case 'J':
828         if (CHECK_ISP_HW_V20()) {
829             rk_aiq_sharp_IQpara_t stSharpIQpara;
830             rk_aiq_sharp_IQpara_t stGetSharpIQpara;
831             stSharpIQpara.module_bits = (1 << ASHARP_MODULE_SHARP) | (1 << ASHARP_MODULE_EDGEFILTER) ;
832             rk_aiq_user_api_asharp_GetIQPara(ctx, &stSharpIQpara);
833             for(int m = 0; m < 3; m++) {
834                 for(int k = 0; k < 2; k++) {
835                     for(int i = 0; i < CALIBDB_NR_SHARP_MAX_ISO_LEVEL; i++ ) {
836                         stSharpIQpara.stSharpPara.mode_cell[m].setting[k].sharp_iso[i].hratio = 1.9;
837                         stSharpIQpara.stSharpPara.mode_cell[m].setting[k].sharp_iso[i].lratio = 0.4;
838                         stSharpIQpara.stSharpPara.mode_cell[m].setting[k].sharp_iso[i].mf_sharp_ratio = 5.0;
839                         stSharpIQpara.stSharpPara.mode_cell[m].setting[k].sharp_iso[i].hf_sharp_ratio = 6.0;
840 
841                         stSharpIQpara.stEdgeFltPara.mode_cell[m].setting[k].edgeFilter_iso[i].edge_thed = 33.0;
842                         stSharpIQpara.stEdgeFltPara.mode_cell[m].setting[k].edgeFilter_iso[i].local_alpha = 0.5;
843                     }
844                 }
845             }
846             rk_aiq_user_api_asharp_SetIQPara(ctx, &stSharpIQpara);
847             sleep(5);
848             rk_aiq_user_api_asharp_GetIQPara(ctx, &stGetSharpIQpara);
849             for(int m = 0; m < 1; m++) {
850                 for(int k = 0; k < 1; k++) {
851                     for(int i = 0; i < CALIBDB_NR_SHARP_MAX_ISO_LEVEL; i++ ) {
852                         printf("\n\n!!!!!!!!!!set:%d cell:%d !!!!!!!!!!\n", k, i);
853                         printf("oyyf222 sharp:%f %f ratio:%f %f\n",
854                                stGetSharpIQpara.stSharpPara.mode_cell[m].setting[k].sharp_iso[i].lratio,
855                                stGetSharpIQpara.stSharpPara.mode_cell[m].setting[k].sharp_iso[i].hratio,
856                                stGetSharpIQpara.stSharpPara.mode_cell[m].setting[k].sharp_iso[i].mf_sharp_ratio,
857                                stGetSharpIQpara.stSharpPara.mode_cell[m].setting[k].sharp_iso[i].hf_sharp_ratio);
858 
859                         printf("oyyf222 edgefilter:%f %f\n",
860                                stGetSharpIQpara.stEdgeFltPara.mode_cell[m].setting[k].edgeFilter_iso[i].edge_thed,
861                                stGetSharpIQpara.stEdgeFltPara.mode_cell[m].setting[k].edgeFilter_iso[i].local_alpha);
862 
863                         printf("!!!!!!!!!!set:%d cell:%d  end !!!!!!!!!!\n", k, i);
864                     }
865                 }
866             }
867         }
868         break;
869     case 'K':
870         printf("test mirro, flip\n");
871         bool mirror, flip;
872         rk_aiq_uapi_getMirrorFlip(ctx, &mirror, &flip);
873         printf("oringinal mir %d, flip %d \n", mirror, flip);
874         mirror = true;
875         flip = true;
876         printf("set mir %d, flip %d \n", mirror, flip);
877         rk_aiq_uapi_setMirroFlip(ctx, true, true, 3);
878         rk_aiq_uapi_getMirrorFlip(ctx, &mirror, &flip);
879         printf("after set mir %d, flip %d \n", mirror, flip);
880         break;
881     case 'L':
882         printf("test fec correct level100\n");
883         rk_aiq_uapi_setFecCorrectLevel(ctx, 100);
884         break;
885     case 'M':
886         printf("test fec correct level255\n");
887         rk_aiq_uapi_setFecCorrectLevel(ctx, 255);
888         break;
889     case 'N':
890     {
891         rk_aiq_dpcc_attrib_V20_t attr;
892         rk_aiq_user_api2_adpcc_GetAttrib(ctx, &attr);
893         rk_aiq_user_api2_adpcc_SetAttrib(ctx, &attr);
894         adebayer_attrib_t attr2;
895         rk_aiq_user_api2_adebayer_SetAttrib(ctx, attr2);
896     }
897     break;
898     case 'O':
899         printf("test not bypass fec\n");
900         rk_aiq_uapi_setFecBypass(ctx, false);
901         break;
902     case 'P':
903     {
904         int work_mode = demo_ctx->hdrmode;
905         rk_aiq_working_mode_t new_mode;
906         if (work_mode == RK_AIQ_WORKING_MODE_NORMAL)
907             new_mode = RK_AIQ_WORKING_MODE_ISP_HDR3;
908         else
909             new_mode = RK_AIQ_WORKING_MODE_NORMAL;
910         printf("switch work mode from %d to %d\n", work_mode, new_mode);
911         *const_cast<int*>(&demo_ctx->hdrmode) = work_mode = new_mode;
912         rk_aiq_uapi_sysctl_swWorkingModeDyn(ctx, new_mode);
913     }
914     break;
915     case 'Q':
916     {
917         rk_aiq_rotation_t rot = RK_AIQ_ROTATION_90;
918         rk_aiq_mems_sensor_intf_t intf = {0};
919         const char* main_scene = "good";
920         const char* sub_scene = "bad";
921         rk_aiq_uapi2_sysctl_setSharpFbcRotation(ctx, rot);
922         rk_aiq_uapi2_sysctl_setMulCamConc(ctx, true);
923         rk_aiq_uapi2_sysctl_regMemsSensorIntf(ctx, &intf);
924         rk_aiq_uapi2_sysctl_switch_scene(ctx, main_scene, sub_scene);
925     }
926     break;
927     case 'R':
928     {
929         rk_aiq_cpsl_info_t cpsl_info;
930         rk_aiq_cpsl_cap_t cpsl_cap;
931         rk_aiq_uapi2_sysctl_getCpsLtInfo(ctx, &cpsl_info);
932         rk_aiq_uapi2_sysctl_queryCpsLtCap(ctx, &cpsl_cap);
933         printf("sensitivity: %f, cap sensitivity: %f:%f:%f\n", cpsl_info.sensitivity,
934                cpsl_cap.sensitivity.min, cpsl_cap.sensitivity.step, cpsl_cap.sensitivity.max);
935         rk_aiq_cpsl_cfg_t cpsl_cfg;
936         rk_aiq_uapi2_sysctl_setCpsLtCfg(ctx, &cpsl_cfg);
937     }
938     break;
939     case 'S':
940         printf("test ldch correct level100\n");
941         rk_aiq_uapi_setLdchCorrectLevel(ctx, 100);
942         break;
943     case 'T':
944     {
945         rk_aiq_rect_t info;
946         rk_aiq_uapi2_sysctl_getCrop(ctx, &info);
947         printf("left:%d, top:%d, width:%d, height:%d\n", info.left, info.top, info.width, info.height);
948         info.left += 64;
949         info.top += 64;
950         info.width = 640;
951         info.height = 480;
952         //rk_aiq_uapi2_sysctl_setCrop(ctx, info);
953     }
954     break;
955     case 'U':
956     {
957         char output_dir[64] = {0};
958         printf("test to capture raw sync\n");
959         rk_aiq_uapi_debug_captureRawSync(ctx, CAPTURE_RAW_SYNC, 5, "/tmp", output_dir);
960         printf("Raw's storage directory is (%s)\n", output_dir);
961     }
962     break;
963     case 'V':
964     {
965         test_update_iqfile(demo_ctx);
966     }
967     break;
968     case 'W':
969     {
970         rk_aiq_ver_info_t vers;
971         rk_aiq_uapi2_get_version_info(&vers);
972         printf("aiq ver %s, parser ver %s, magic code %d, awb ver %s\n"
973                "ae ver %s, af ver %s, ahdr ver %s\n", vers.aiq_ver,
974                vers.iq_parser_ver, vers.iq_parser_magic_code,
975                vers.awb_algo_ver, vers.ae_algo_ver,
976                vers.af_algo_ver, vers.ahdr_algo_ver);
977     }
978     break;
979     case 'X':
980     {
981         for (int type = RK_AIQ_ALGO_TYPE_AE; type < RK_AIQ_ALGO_TYPE_MAX; type++)
982         {
983             bool ret = rk_aiq_uapi2_sysctl_getAxlibStatus(ctx, type, 0);
984             printf("%d is %s, \n", type, (ret ? "enabled" : "disabled or unregistered"));
985 
986             const RkAiqAlgoContext* algo_ptr = rk_aiq_uapi2_sysctl_getEnabledAxlibCtx(ctx, type);
987             if (algo_ptr) {
988                 printf("type: %d ==> algo_ptr: %p\n", type, algo_ptr);
989             }
990             if (ret == false) {
991                 bool ret2 = rk_aiq_uapi2_sysctl_enableAxlib(ctx, type, 0, !ret);
992             }
993         }
994     }
995     break;
996     case 'Y':
997     {
998         rk_aiq_lsc_querry_info_t info;
999         rk_aiq_user_api2_alsc_QueryLscInfo(ctx, &info);
1000         printf("LSC: enable: %s, \n", (info.lsc_en ? "true" : "false"));
1001         printf("r: %d, %d, %d \n", info.r_data_tbl[0], info.r_data_tbl[1], info.r_data_tbl[2]);
1002         printf("gr: %d, %d, %d \n", info.gr_data_tbl[0], info.gr_data_tbl[1], info.gr_data_tbl[2]);
1003         printf("gb: %d, %d, %d \n", info.gb_data_tbl[0], info.gb_data_tbl[1], info.gb_data_tbl[2]);
1004         printf("b: %d, %d, %d \n", info.b_data_tbl[0], info.b_data_tbl[1], info.b_data_tbl[2]);
1005     }
1006     break;
1007     case 'Z':
1008     {
1009         rk_aiq_static_info_t info;
1010         rk_aiq_uapi2_sysctl_enumStaticMetas(0, &info);
1011         printf("isp version: %d, sensor name: %s\n", info.isp_hw_ver, info.sensor_info.sensor_name);
1012     }
1013     case '[':
1014         set_ae_onoff(ctx, true);
1015         printf("set ae on\n");
1016         break;
1017     case ']':
1018         set_ae_onoff(ctx, false);
1019         printf("set ae off\n");
1020         break;
1021     default:
1022         break;
1023     }
1024 }
1025 #endif
1026 
errno_exit(demo_context_t * ctx,const char * s)1027 static void errno_exit(demo_context_t *ctx, const char *s)
1028 {
1029     ERR("%s: %s error %d, %s\n", get_sensor_name(ctx), s, errno, strerror(errno));
1030     //exit(EXIT_FAILURE);
1031 }
1032 
xioctl(int fh,int request,void * arg)1033 static int xioctl(int fh, int request, void *arg)
1034 {
1035     int r;
1036     do {
1037         r = ioctl(fh, request, arg);
1038     } while (-1 == r && EINTR == errno);
1039     return r;
1040 }
1041 
get_value_from_file(const char * path,int * value,int * frameId)1042 static bool get_value_from_file(const char* path, int* value, int* frameId)
1043 {
1044     const char *delim = " ";
1045     char buffer[16] = {0};
1046     int fp;
1047 
1048     fp = open(path, O_RDONLY | O_SYNC);
1049     if (fp) {
1050         if (read(fp, buffer, sizeof(buffer)) > 0) {
1051             char *p = nullptr;
1052 
1053             p = strtok(buffer, delim);
1054             if (p != nullptr) {
1055                 *value = atoi(p);
1056                 p = strtok(nullptr, delim);
1057                 if (p != nullptr)
1058                     *frameId = atoi(p);
1059             }
1060         }
1061         close(fp);
1062         return true;
1063     }
1064 
1065     return false;
1066 }
1067 
write_yuv_to_file(const void * p,int size,int sequence,demo_context_t * ctx)1068 static int write_yuv_to_file(const void *p,
1069                              int size, int sequence, demo_context_t *ctx)
1070 {
1071     char file_name[64] = {0};
1072 
1073     snprintf(file_name, sizeof(file_name),
1074              "%s/frame%d.yuv",
1075              ctx->yuv_dir_path,
1076              sequence);
1077     ctx->fp = fopen(file_name, "wb+");
1078     if (ctx->fp == NULL) {
1079         ERR("fopen yuv file %s failed!\n", file_name);
1080         return -1;
1081     }
1082 
1083     fwrite(p, size, 1, ctx->fp);
1084     fflush(ctx->fp);
1085 
1086     if (ctx->fp) {
1087         fclose(ctx->fp);
1088         ctx->fp = NULL;
1089     }
1090 
1091     for (int i = 0; i < ctx->capture_yuv_num; i++)
1092         printf("<");
1093 
1094     printf("\n");
1095     // printf("write frame%d yuv\n", sequence);
1096 
1097     return 0;
1098 }
1099 
creat_yuv_dir(const char * path,demo_context_t * ctx)1100 static int creat_yuv_dir(const char* path, demo_context_t *ctx)
1101 {
1102     time_t now;
1103     struct tm* timenow;
1104 
1105     if (!path)
1106         return -1;
1107 
1108     time(&now);
1109     timenow = localtime(&now);
1110     snprintf(ctx->yuv_dir_path, sizeof(ctx->yuv_dir_path),
1111              "%s/yuv_%04d-%02d-%02d_%02d-%02d-%02d",
1112              path,
1113              timenow->tm_year + 1900,
1114              timenow->tm_mon + 1,
1115              timenow->tm_mday,
1116              timenow->tm_hour,
1117              timenow->tm_min,
1118              timenow->tm_sec);
1119 
1120     // printf("mkdir %s for capturing yuv!\n", yuv_dir_path);
1121 
1122     if(mkdir(ctx->yuv_dir_path, 0755) < 0) {
1123         printf("mkdir %s error!!!\n", ctx->yuv_dir_path);
1124         return -1;
1125     }
1126 
1127     ctx->_is_yuv_dir_exist = true;
1128 
1129     return 0;
1130 }
1131 
process_image(const void * p,int sequence,int size,demo_context_t * ctx)1132 static void process_image(const void *p, int sequence, int size, demo_context_t *ctx)
1133 {
1134     if (ctx->fp && sequence >= ctx->skipCnt && ctx->outputCnt-- > 0) {
1135         printf(">\n");
1136         fwrite(p, size, 1, ctx->fp);
1137         fflush(ctx->fp);
1138         fsync(fileno(ctx->fp));
1139     } else if (ctx->fp && sequence >= ctx->skipCnt && ctx->outputCnt-- == 0) {
1140         fclose(ctx->fp);
1141         ctx->fp = NULL;
1142     } else if (ctx->writeFileSync) {
1143         int ret = 0;
1144         if (!ctx->is_capture_yuv) {
1145             char file_name[32] = {0};
1146             int rawFrameId = 0;
1147 
1148             snprintf(file_name, sizeof(file_name), "%s/%s",
1149                      CAPTURE_RAW_PATH, CAPTURE_CNT_FILENAME);
1150             get_value_from_file(file_name, &ctx->capture_yuv_num, &rawFrameId);
1151 
1152             /*
1153              * printf("%s: rawFrameId: %d, sequence: %d\n", __FUNCTION__,
1154              *        rawFrameId, sequence);
1155              */
1156 
1157             sequence += 1;
1158             if (ctx->capture_yuv_num > 0 && \
1159                     ((sequence >= rawFrameId && rawFrameId > 0) || sequence < 2))
1160                 ctx->is_capture_yuv = true;
1161         }
1162 
1163         if (ctx->is_capture_yuv) {
1164             if (!ctx->_is_yuv_dir_exist) {
1165                 creat_yuv_dir(DEFAULT_CAPTURE_RAW_PATH, ctx);
1166             }
1167 
1168             if (ctx->_is_yuv_dir_exist) {
1169                 write_yuv_to_file(p, size, sequence, ctx);
1170                 rk_aiq_uapi2_debug_captureRawNotify(ctx->aiq_ctx);
1171             }
1172 
1173             if (ctx->capture_yuv_num-- == 0) {
1174                 ctx->is_capture_yuv = false;
1175                 ctx->_is_yuv_dir_exist = false;
1176             }
1177         }
1178     }
1179 }
1180 
read_frame(demo_context_t * ctx)1181 static int read_frame(demo_context_t *ctx)
1182 {
1183     struct v4l2_buffer buf;
1184     int i, bytesused;
1185 
1186     CLEAR(buf);
1187 
1188     buf.type = ctx->buf_type;
1189     buf.memory = V4L2_MEMORY_MMAP;
1190 
1191     struct v4l2_plane planes[FMT_NUM_PLANES];
1192     memset(planes, 0, sizeof(struct v4l2_plane)*FMT_NUM_PLANES);
1193     if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == ctx->buf_type) {
1194         buf.m.planes = planes;
1195         buf.length = FMT_NUM_PLANES;
1196     }
1197 
1198     if (-1 == xioctl(ctx->fd, VIDIOC_DQBUF, &buf))
1199         errno_exit(ctx, "VIDIOC_DQBUF");
1200 
1201     i = buf.index;
1202 
1203     if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == ctx->buf_type)
1204         bytesused = buf.m.planes[0].bytesused;
1205     else
1206         bytesused = buf.bytesused;
1207 
1208 #if ISPDEMO_ENABLE_DRM
1209 #ifdef ISPFEC_API
1210     int buf_fd = -1;
1211     void* buf_addr = NULL;
1212 
1213     buf_fd = ctx->buffers[i].export_fd;
1214     buf_addr = ctx->buffers[i].start;
1215 
1216     int dstFd = g_drm_buf_pic_out.dmabuf_fd;
1217     buf_fd = dstFd;
1218     buf_addr = g_drm_buf_pic_out.map;
1219     rk_ispfec_api_process(g_ispfec_ctx, ctx->buffers[i].export_fd, dstFd);
1220 #endif
1221 
1222     if (ctx->vop) {
1223         int dispWidth, dispHeight;
1224 
1225         if (ctx->width > 1920)
1226             dispWidth = 1920;
1227         else
1228             dispWidth = ctx->width;
1229 
1230         if (ctx->height > 1088)
1231             dispHeight = 1088;
1232         else
1233             dispHeight = ctx->height;
1234 
1235 #if ISPDEMO_ENABLE_RGA
1236         if (strlen(ctx->dev_name) && strlen(ctx->dev_name2)) {
1237             if (ctx->dev_using == 1) {
1238 #ifdef ISPFEC_API
1239                 display_win1(buf_addr, buf_fd,  RK_FORMAT_YCbCr_420_SP, dispWidth, dispHeight, 0);
1240 #else
1241                 display_win1(ctx->buffers[i].start, ctx->buffers[i].export_fd,  RK_FORMAT_YCbCr_420_SP, dispWidth, dispHeight, 0);
1242 #endif
1243             } else {
1244 #ifdef ISPFEC_API
1245                 display_win2(buf_addr, buf_fd,  RK_FORMAT_YCbCr_420_SP, dispWidth, dispHeight, 0);
1246 #else
1247                 display_win2(ctx->buffers[i].start, ctx->buffers[i].export_fd,  RK_FORMAT_YCbCr_420_SP, dispWidth, dispHeight, 0);
1248 #endif
1249             }
1250         } else {
1251 #else
1252         {
1253 #endif
1254             drmDspFrame(ctx->width, ctx->height, dispWidth, dispHeight, ctx->buffers[i].export_fd,
1255                        ctx->buffers[i].start, DRM_FORMAT_NV12);
1256         }
1257     }
1258 #endif
1259 
1260 #ifdef ISPFEC_API
1261     process_image(buf_addr,  buf.sequence, bytesused, ctx);
1262 #else
1263     process_image(ctx->buffers[i].start,  buf.sequence, bytesused, ctx);
1264 #endif
1265 
1266     if (-1 == xioctl(ctx->fd, VIDIOC_QBUF, &buf))
1267         errno_exit(ctx, "VIDIOC_QBUF");
1268 
1269     return 1;
1270 }
1271 
1272 static int read_frame_pp_oneframe(demo_context_t *ctx)
1273 {
1274     struct v4l2_buffer buf;
1275     struct v4l2_buffer buf_pp;
1276     int i, ii = 0, bytesused;
1277     static int first_time = 1;
1278 
1279     CLEAR(buf);
1280     // dq one buf from isp mp
1281     DBG("------ dq 1 from isp mp --------------\n");
1282     buf.type = ctx->buf_type;
1283     buf.memory = V4L2_MEMORY_MMAP;
1284 
1285     struct v4l2_plane planes[FMT_NUM_PLANES];
1286     if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == ctx->buf_type) {
1287         buf.m.planes = planes;
1288         buf.length = FMT_NUM_PLANES;
1289     }
1290 
1291     if (-1 == xioctl(ctx->fd_isp_mp, VIDIOC_DQBUF, &buf))
1292         errno_exit(ctx, "VIDIOC_DQBUF");
1293 
1294     i = buf.index;
1295 
1296     if (first_time ) {
1297         DBG("------ dq 2 from isp mp --------------\n");
1298         if (-1 == xioctl(ctx->fd_isp_mp, VIDIOC_DQBUF, &buf))
1299             errno_exit(ctx, "VIDIOC_DQBUF");
1300 
1301         ii = buf.index;
1302     }
1303 
1304     if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == ctx->buf_type)
1305         bytesused = buf.m.planes[0].bytesused;
1306     else
1307         bytesused = buf.bytesused;
1308 
1309     // queue to ispp input
1310     DBG("------ queue 1 index %d to ispp input --------------\n", i);
1311     CLEAR(buf_pp);
1312     buf_pp.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1313     buf_pp.memory = V4L2_MEMORY_DMABUF;
1314     buf_pp.index = i;
1315 
1316     struct v4l2_plane planes_pp[FMT_NUM_PLANES];
1317     memset(planes_pp, 0, sizeof(planes_pp));
1318     buf_pp.m.planes = planes_pp;
1319     buf_pp.length = FMT_NUM_PLANES;
1320     buf_pp.m.planes[0].m.fd = ctx->buffers_mp[i].export_fd;
1321 
1322     if (-1 == xioctl(ctx->fd_pp_input, VIDIOC_QBUF, &buf_pp))
1323         errno_exit(ctx, "VIDIOC_QBUF");
1324 
1325     if (first_time ) {
1326         DBG("------ queue 2 index %d to ispp input --------------\n", ii);
1327         buf_pp.index = ii;
1328         buf_pp.m.planes[0].m.fd = ctx->buffers_mp[ii].export_fd;
1329         if (-1 == xioctl(ctx->fd_pp_input, VIDIOC_QBUF, &buf_pp))
1330             errno_exit(ctx, "VIDIOC_QBUF");
1331     }
1332     // read frame from ispp sharp/scale
1333     DBG("------ readframe from output --------------\n");
1334     read_frame(ctx);
1335     // dq from pp input
1336     DBG("------ dq 1 from ispp input--------------\n");
1337     if (-1 == xioctl(ctx->fd_pp_input, VIDIOC_DQBUF, &buf_pp))
1338         errno_exit(ctx, "VIDIOC_DQBUF");
1339     // queue back to mp
1340     DBG("------ queue 1 index %d back to isp mp--------------\n", buf_pp.index);
1341     buf.index = buf_pp.index;
1342     if (-1 == xioctl(ctx->fd_isp_mp, VIDIOC_QBUF, &buf))
1343         errno_exit(ctx, "VIDIOC_QBUF");
1344 
1345     first_time = 0;
1346     return 1;
1347 }
1348 
1349 static void mainloop(demo_context_t *ctx)
1350 {
1351     while ((ctx->frame_count == -1) || (ctx->frame_count-- > 0)) {
1352         if (ctx->pponeframe)
1353             read_frame_pp_oneframe(ctx);
1354         else
1355             read_frame(ctx);
1356     }
1357 }
1358 
1359 static void stop_capturing(demo_context_t *ctx)
1360 {
1361     enum v4l2_buf_type type;
1362 
1363     type = ctx->buf_type;
1364     if (-1 == xioctl(ctx->fd, VIDIOC_STREAMOFF, &type))
1365         errno_exit(ctx, "VIDIOC_STREAMOFF");
1366 }
1367 
1368 static void stop_capturing_pp_oneframe(demo_context_t *ctx)
1369 {
1370     enum v4l2_buf_type type;
1371 
1372     type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1373     if (-1 == xioctl(ctx->fd_pp_input, VIDIOC_STREAMOFF, &type))
1374         errno_exit(ctx, "VIDIOC_STREAMOFF ppinput");
1375     type = ctx->buf_type;
1376     if (-1 == xioctl(ctx->fd_isp_mp, VIDIOC_STREAMOFF, &type))
1377         errno_exit(ctx, "VIDIOC_STREAMOFF ispmp");
1378 }
1379 
1380 static void start_capturing(demo_context_t *ctx)
1381 {
1382     unsigned int i;
1383     enum v4l2_buf_type type;
1384 
1385     for (i = 0; i < ctx->n_buffers; ++i) {
1386         struct v4l2_buffer buf;
1387 
1388         CLEAR(buf);
1389         buf.type = ctx->buf_type;
1390         buf.memory = V4L2_MEMORY_MMAP;
1391         buf.index = i;
1392 
1393         if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == ctx->buf_type) {
1394             struct v4l2_plane planes[FMT_NUM_PLANES];
1395 
1396             buf.m.planes = planes;
1397             buf.length = FMT_NUM_PLANES;
1398         }
1399         if (-1 == xioctl(ctx->fd, VIDIOC_QBUF, &buf))
1400             errno_exit(ctx, "VIDIOC_QBUF");
1401     }
1402     type = ctx->buf_type;
1403     DBG("%s:-------- stream on output -------------\n", get_sensor_name(ctx));
1404 
1405     if (-1 == xioctl(ctx->fd, VIDIOC_STREAMON, &type))
1406         errno_exit(ctx, "VIDIOC_STREAMON");
1407 }
1408 
1409 static void start_capturing_pp_oneframe(demo_context_t *ctx)
1410 {
1411     unsigned int i;
1412     enum v4l2_buf_type type;
1413 
1414     type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1415     DBG("%s:-------- stream on pp input -------------\n", get_sensor_name(ctx));
1416     if (-1 == xioctl(ctx->fd_pp_input, VIDIOC_STREAMON, &type))
1417         errno_exit(ctx, "VIDIOC_STREAMON pp input");
1418 
1419     type = ctx->buf_type;
1420     for (i = 0; i < ctx->n_buffers; ++i) {
1421         struct v4l2_buffer buf;
1422 
1423         CLEAR(buf);
1424         buf.type = ctx->buf_type;
1425         buf.memory = V4L2_MEMORY_MMAP;
1426         buf.index = i;
1427 
1428         if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == ctx->buf_type) {
1429             struct v4l2_plane planes[FMT_NUM_PLANES];
1430 
1431             buf.m.planes = planes;
1432             buf.length = FMT_NUM_PLANES;
1433         }
1434         if (-1 == xioctl(ctx->fd_isp_mp, VIDIOC_QBUF, &buf))
1435             errno_exit(ctx, "VIDIOC_QBUF");
1436     }
1437     DBG("%s:-------- stream on isp mp -------------\n", get_sensor_name(ctx));
1438     if (-1 == xioctl(ctx->fd_isp_mp, VIDIOC_STREAMON, &type))
1439         errno_exit(ctx, "VIDIOC_STREAMON ispmp");
1440 }
1441 
1442 
1443 static void uninit_device(demo_context_t *ctx)
1444 {
1445     unsigned int i;
1446     if (ctx->n_buffers == 0)
1447         return;
1448 
1449     for (i = 0; i < ctx->n_buffers; ++i) {
1450         if (-1 == munmap(ctx->buffers[i].start, ctx->buffers[i].length))
1451             errno_exit(ctx, "munmap");
1452 
1453         close(ctx->buffers[i].export_fd);
1454     }
1455 
1456     free(ctx->buffers);
1457     ctx->n_buffers = 0;
1458 }
1459 
1460 static void uninit_device_pp_oneframe(demo_context_t *ctx)
1461 {
1462     unsigned int i;
1463 
1464     for (i = 0; i < ctx->n_buffers; ++i) {
1465         if (-1 == munmap(ctx->buffers_mp[i].start, ctx->buffers_mp[i].length))
1466             errno_exit(ctx, "munmap");
1467 
1468         close(ctx->buffers_mp[i].export_fd);
1469     }
1470 
1471     free(ctx->buffers_mp);
1472 }
1473 
1474 static void init_mmap(int pp_onframe, demo_context_t *ctx)
1475 {
1476     struct v4l2_requestbuffers req;
1477     int fd_tmp = -1;
1478 
1479     CLEAR(req);
1480 
1481     if (pp_onframe)
1482         fd_tmp = ctx->fd_isp_mp ;
1483     else
1484         fd_tmp = ctx->fd;
1485 
1486     req.count = BUFFER_COUNT;
1487     req.type = ctx->buf_type;
1488     req.memory = V4L2_MEMORY_MMAP;
1489 
1490     struct buffer *tmp_buffers = NULL;
1491 
1492     if (-1 == xioctl(fd_tmp, VIDIOC_REQBUFS, &req)) {
1493         if (EINVAL == errno) {
1494             ERR("%s: %s does not support "
1495                 "memory mapping\n", get_sensor_name(ctx), get_dev_name(ctx));
1496             //exit(EXIT_FAILURE);
1497         } else {
1498             errno_exit(ctx, "VIDIOC_REQBUFS");
1499         }
1500     }
1501 
1502     if (req.count < 2) {
1503         ERR("%s: Insufficient buffer memory on %s\n", get_sensor_name(ctx),
1504             get_dev_name(ctx));
1505         //exit(EXIT_FAILURE);
1506     }
1507 
1508     tmp_buffers = (struct buffer*)calloc(req.count, sizeof(struct buffer));
1509 
1510     if (!tmp_buffers) {
1511         ERR("%s: Out of memory\n", get_sensor_name(ctx));
1512         //exit(EXIT_FAILURE);
1513     }
1514 
1515     if (pp_onframe)
1516         ctx->buffers_mp = tmp_buffers;
1517     else
1518         ctx->buffers = tmp_buffers;
1519 
1520     for (ctx->n_buffers = 0; ctx->n_buffers < req.count; ++ctx->n_buffers) {
1521         struct v4l2_buffer buf;
1522         struct v4l2_plane planes[FMT_NUM_PLANES];
1523         CLEAR(buf);
1524         CLEAR(planes);
1525 
1526         buf.type = ctx->buf_type;
1527         buf.memory = V4L2_MEMORY_MMAP;
1528         buf.index = ctx->n_buffers;
1529 
1530         if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == ctx->buf_type) {
1531             buf.m.planes = planes;
1532             buf.length = FMT_NUM_PLANES;
1533         }
1534 
1535         if (-1 == xioctl(fd_tmp, VIDIOC_QUERYBUF, &buf))
1536             errno_exit(ctx, "VIDIOC_QUERYBUF");
1537 
1538         if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == ctx->buf_type) {
1539             tmp_buffers[ctx->n_buffers].length = buf.m.planes[0].length;
1540             tmp_buffers[ctx->n_buffers].start =
1541                 mmap(NULL /* start anywhere */,
1542                      buf.m.planes[0].length,
1543                      PROT_READ | PROT_WRITE /* required */,
1544                      MAP_SHARED /* recommended */,
1545                      fd_tmp, buf.m.planes[0].m.mem_offset);
1546         } else {
1547             tmp_buffers[ctx->n_buffers].length = buf.length;
1548             tmp_buffers[ctx->n_buffers].start =
1549                 mmap(NULL /* start anywhere */,
1550                      buf.length,
1551                      PROT_READ | PROT_WRITE /* required */,
1552                      MAP_SHARED /* recommended */,
1553                      fd_tmp, buf.m.offset);
1554         }
1555 
1556         if (MAP_FAILED == tmp_buffers[ctx->n_buffers].start)
1557             errno_exit(ctx, "mmap");
1558 
1559         // export buf dma fd
1560         struct v4l2_exportbuffer expbuf;
1561         xcam_mem_clear (expbuf);
1562         expbuf.type = ctx->buf_type;
1563         expbuf.index = ctx->n_buffers;
1564         expbuf.flags = O_CLOEXEC;
1565         if (xioctl(fd_tmp, VIDIOC_EXPBUF, &expbuf) < 0) {
1566             errno_exit(ctx, "get dma buf failed\n");
1567         } else {
1568             DBG("%s: get dma buf(%d)-fd: %d\n", get_sensor_name(ctx), ctx->n_buffers, expbuf.fd);
1569         }
1570         tmp_buffers[ctx->n_buffers].export_fd = expbuf.fd;
1571     }
1572 }
1573 
1574 static void init_input_dmabuf_oneframe(demo_context_t *ctx) {
1575     struct v4l2_requestbuffers req;
1576 
1577     CLEAR(req);
1578 
1579     printf("%s:-------- request pp input buffer -------------\n", get_sensor_name(ctx));
1580     req.count = BUFFER_COUNT;
1581     req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1582     req.memory = V4L2_MEMORY_DMABUF;
1583 
1584     if (-1 == xioctl(ctx->fd_pp_input, VIDIOC_REQBUFS, &req)) {
1585         if (EINVAL == errno) {
1586             ERR("does not support "
1587                 "DMABUF\n");
1588             exit(EXIT_FAILURE);
1589         } else {
1590             errno_exit(ctx, "VIDIOC_REQBUFS");
1591         }
1592     }
1593 
1594     if (req.count < 2) {
1595         ERR("Insufficient buffer memory on %s\n",
1596             get_dev_name(ctx));
1597         exit(EXIT_FAILURE);
1598     }
1599     printf("%s:-------- request isp mp buffer -------------\n", get_sensor_name(ctx));
1600     init_mmap(true, ctx);
1601 }
1602 
1603 static void init_device(demo_context_t *ctx)
1604 {
1605     struct v4l2_capability cap;
1606     struct v4l2_format fmt;
1607 
1608     if (-1 == xioctl(ctx->fd, VIDIOC_QUERYCAP, &cap)) {
1609         if (EINVAL == errno) {
1610             ERR("%s: %s is no V4L2 device\n", get_sensor_name(ctx),
1611                 get_dev_name(ctx));
1612             //exit(EXIT_FAILURE);
1613         } else {
1614             errno_exit(ctx, "VIDIOC_QUERYCAP");
1615         }
1616     }
1617 
1618     if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) &&
1619             !(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE)) {
1620         ERR("%s: %s is not a video capture device, capabilities: %x\n",
1621             get_sensor_name(ctx), get_dev_name(ctx), cap.capabilities);
1622         //exit(EXIT_FAILURE);
1623     }
1624 
1625     if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
1626         ERR("%s: %s does not support streaming i/o\n", get_sensor_name(ctx),
1627             get_dev_name(ctx));
1628         //exit(EXIT_FAILURE);
1629     }
1630 
1631     if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
1632         ctx->buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1633         CLEAR(fmt);
1634         fmt.type = ctx->buf_type;
1635         fmt.fmt.pix.width = ctx->width;
1636         fmt.fmt.pix.height = ctx->height;
1637         fmt.fmt.pix.pixelformat = ctx->format;
1638         fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
1639         if (ctx->limit_range)
1640             fmt.fmt.pix.quantization = V4L2_QUANTIZATION_LIM_RANGE;
1641         else
1642             fmt.fmt.pix.quantization = V4L2_QUANTIZATION_FULL_RANGE;
1643     } else if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE) {
1644         ctx->buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1645         CLEAR(fmt);
1646         fmt.type = ctx->buf_type;
1647         fmt.fmt.pix_mp.width = ctx->width;
1648         fmt.fmt.pix_mp.height = ctx->height;
1649         fmt.fmt.pix_mp.pixelformat = ctx->format;
1650         fmt.fmt.pix_mp.field = V4L2_FIELD_INTERLACED;
1651         if (ctx->limit_range)
1652             fmt.fmt.pix_mp.quantization = V4L2_QUANTIZATION_LIM_RANGE;
1653         else
1654             fmt.fmt.pix_mp.quantization = V4L2_QUANTIZATION_FULL_RANGE;
1655     }
1656 
1657     if (-1 == xioctl(ctx->fd, VIDIOC_S_FMT, &fmt))
1658         errno_exit(ctx, "VIDIOC_S_FMT");
1659 
1660     init_mmap(false, ctx);
1661 }
1662 
1663 static void init_device_pp_oneframe(demo_context_t *ctx)
1664 {
1665     // TODO, set format and link, now do with setup_link.sh
1666     init_input_dmabuf_oneframe(ctx);
1667 }
1668 
1669 static void close_device(demo_context_t *ctx)
1670 {
1671     if (-1 == close(ctx->fd))
1672         errno_exit(ctx, "close");
1673 
1674     ctx->fd = -1;
1675 }
1676 
1677 static void open_device(demo_context_t *ctx)
1678 {
1679     printf("-------- open output dev_name:%s -------------\n", get_dev_name(ctx));
1680     ctx->fd = open(get_dev_name(ctx), O_RDWR /* required */ /*| O_NONBLOCK*/, 0);
1681 
1682     if (-1 == ctx->fd) {
1683         ERR("Cannot open '%s': %d, %s\n",
1684             get_dev_name(ctx), errno, strerror(errno));
1685         exit(EXIT_FAILURE);
1686     }
1687 }
1688 
1689 static void close_device_pp_oneframe(demo_context_t *ctx)
1690 {
1691     if (-1 == close(ctx->fd_pp_input))
1692         errno_exit(ctx, "close");
1693 
1694     ctx->fd_pp_input = -1;
1695 
1696     if (-1 == close(ctx->fd_isp_mp))
1697         errno_exit(ctx, "close");
1698 
1699     ctx->fd_isp_mp = -1;
1700 }
1701 
1702 static void open_device_pp_oneframe(demo_context_t *ctx)
1703 {
1704     printf("-------- open pp input(video13) -------------\n");
1705     ctx->fd_pp_input = open("/dev/video13", O_RDWR /* required */ /*| O_NONBLOCK*/, 0);
1706 
1707     if (-1 == ctx->fd_pp_input) {
1708         ERR("Cannot open '%s': %d, %s\n",
1709             get_dev_name(ctx), errno, strerror(errno));
1710         exit(EXIT_FAILURE);
1711     }
1712 
1713     printf("-------- open isp mp(video0) -------------\n");
1714     ctx->fd_isp_mp = open("/dev/video0", O_RDWR /* required */ /*| O_NONBLOCK*/, 0);
1715 
1716     if (-1 == ctx->fd_isp_mp ) {
1717         ERR("Cannot open '%s': %d, %s\n",
1718             get_dev_name(ctx), errno, strerror(errno));
1719         exit(EXIT_FAILURE);
1720     }
1721 }
1722 
1723 static void uninit_device_pp_onframe(demo_context_t *ctx)
1724 {
1725     unsigned int i;
1726 
1727     for (i = 0; i < ctx->n_buffers; ++i) {
1728         if (-1 == munmap(ctx->buffers_mp[i].start, ctx->buffers_mp[i].length))
1729             errno_exit(ctx, "munmap");
1730         close(ctx->buffers_mp[i].export_fd);
1731     }
1732 
1733     free(ctx->buffers_mp);
1734 }
1735 
1736 static void parse_args(int argc, char **argv, demo_context_t *ctx)
1737 {
1738     int c;
1739     int digit_optind = 0;
1740     optind = 0;
1741     while (1) {
1742         int this_option_optind = optind ? optind : 1;
1743         int option_index = 0;
1744         static struct option long_options[] = {
1745             {"width",    required_argument, 0, 'w' },
1746             {"height",   required_argument, 0, 'h' },
1747             {"format",   required_argument, 0, 'f' },
1748             {"device",   required_argument, 0, 'd' },
1749             {"device2",   required_argument, 0, 'i' },
1750             {"device3",   required_argument, 0, 'g' },
1751             {"device4",   required_argument, 0, 'j' },
1752             {"stream-to",   required_argument, 0, 'o' },
1753             {"stream-count",   required_argument, 0, 'n' },
1754             {"stream-skip",   required_argument, 0, 'k' },
1755             {"count",    required_argument, 0, 'c' },
1756             {"help",     no_argument,       0, 'p' },
1757             {"silent",   no_argument,       0, 's' },
1758             {"vop",   no_argument,       0, 'v' },
1759             {"rkaiq",   no_argument,       0, 'r' },
1760             {"pponeframe",   no_argument,       0, 'm' },
1761             {"hdr",   required_argument,       0, 'a' },
1762             {"sync-to-raw", no_argument, 0, 'e' },
1763             {"limit", no_argument, 0, 'l' },
1764             {"ctl", required_argument, 0, 't' },
1765             {"iqpath", required_argument, 0, '1' },
1766             {"orp", required_argument, 0, '2' },
1767             //{"sensor",   required_argument,       0, 'b' },
1768             {"camgroup",   no_argument,       0, '3' },
1769             {0,          0,                 0,  0  }
1770         };
1771 
1772         //c = getopt_long(argc, argv, "w:h:f:i:d:o:c:ps",
1773         c = getopt_long(argc, argv, "w:h:f:i:g:j:d:o:c:n:k:a:t:1:2:3mpsevrl",
1774                         long_options, &option_index);
1775         if (c == -1)
1776             break;
1777 
1778         switch (c) {
1779         case 'c':
1780             ctx->frame_count = atoi(optarg);
1781             break;
1782         case 'w':
1783             ctx->width = atoi(optarg);
1784             break;
1785         case 'h':
1786             ctx->height = atoi(optarg);
1787             break;
1788         case 'f':
1789             ctx->format = v4l2_fourcc(optarg[0], optarg[1], optarg[2], optarg[3]);
1790             break;
1791         case 'd':
1792             strcpy(ctx->dev_name, optarg);
1793             break;
1794         case 'i':
1795             strcpy(ctx->dev_name2, optarg);
1796             break;
1797         case 'g':
1798             strcpy(ctx->dev_name3, optarg);
1799             break;
1800         case 'j':
1801             strcpy(ctx->dev_name4, optarg);
1802             break;
1803         case 'o':
1804             strcpy(ctx->out_file, optarg);
1805             ctx->writeFile = 1;
1806             break;
1807         case 'n':
1808             ctx->outputCnt = atoi(optarg);
1809             break;
1810         case 'k':
1811             ctx->skipCnt = atoi(optarg);
1812             break;
1813         case 's':
1814             silent = 1;
1815             break;
1816         case 'v':
1817             ctx->vop = 1;
1818             break;
1819         case 'r':
1820             ctx->rkaiq = 1;
1821             break;
1822         case 'm':
1823             ctx->pponeframe = 1;
1824             break;
1825         case 'a':
1826             ctx->hdrmode = atoi(optarg);
1827             break;
1828         case 'e':
1829             ctx->writeFileSync = 1;
1830             break;
1831         case 'l':
1832             ctx->limit_range = 1;
1833             break;
1834         case '1':
1835             strcpy(ctx->iqpath, optarg);
1836             break;
1837         case '2':
1838         {
1839             // parse raw fmt
1840             char* raw_dir = strstr(optarg, ",");
1841             size_t raw_dir_str_len = raw_dir - optarg;
1842             if (!raw_dir) {
1843                 printf("orp dir error ! \n");
1844                 exit(-1);
1845             }
1846             strncpy(ctx->orppath, optarg, raw_dir_str_len);
1847 
1848             char* raw_fmt_w_start = raw_dir + 1;
1849             int raw_width = atoi(raw_fmt_w_start);
1850             if (raw_width == 0) {
1851                 printf("orp raw_width error ! \n");
1852                 exit(-1);
1853             }
1854             ctx->orpRawW = raw_width;
1855             char* raw_fmt_h_start = strstr(raw_fmt_w_start, ":") + 1;
1856             if (!raw_fmt_h_start) {
1857                 printf("orp raw_h error ! \n");
1858                 exit(-1);
1859             }
1860             int raw_height = atoi(raw_fmt_h_start);
1861             ctx->orpRawH = raw_height;
1862 
1863             char* raw_fmt_pix_start = strstr(raw_fmt_h_start, ":") + 1;
1864             strcpy(ctx->orpRawFmt, raw_fmt_pix_start);
1865 
1866             printf("orp_path:%s, w:%d,h:%d, pix:%s \n",
1867                    ctx->orppath, raw_width, raw_height, raw_fmt_pix_start);
1868             ctx->isOrp = true;
1869         }
1870         break;
1871         case 't':
1872             ctx->ctl_type = atoi(optarg);
1873             break;
1874         case '3':
1875             ctx->camGroup = true;
1876             break;
1877         case '?':
1878         case 'p':
1879             ERR("Usage: %s to capture rkisp1 frames\n"
1880                 "         --width,  default 640,             optional, width of image\n"
1881                 "         --height, default 480,             optional, height of image\n"
1882                 "         --format, default NV12,            optional, fourcc of format\n"
1883                 "         --count,  default 1000,            optional, how many frames to capture\n"
1884                 "         --device,                          required, path of video device1\n"
1885                 "         --device2,                         required, path of video device2\n"
1886                 "         --device3,                         required, path of video device3\n"
1887                 "         --device4,                         required, path of video device4\n"
1888                 "         --stream-to,                       optional, output file path, if <file> is '-', then the data is written to stdout\n"
1889                 "         --stream-count, default 3          optional, how many frames to write files\n"
1890                 "         --stream-skip, default 30          optional, how many frames to skip befor writing file\n"
1891                 "         --vop,                             optional, drm display\n"
1892                 "         --rkaiq,                           optional, auto image quality\n"
1893                 "         --silent,                          optional, subpress debug log\n"
1894                 "         --pponeframe,                      optional, pp oneframe readback mode\n"
1895                 "         --hdr <val>,                       optional, hdr mode, val 2 means hdrx2, 3 means hdrx3 \n"
1896                 "         --sync-to-raw,                     optional, write yuv files in sync with raw\n"
1897                 "         --limit,                           optional, yuv limit range\n"
1898                 "         --ctl <val>,                       optional, sysctl procedure test \n"
1899                 "         --iqpath <val>,                    optional, absolute path of iq file dir \n"
1900                 "         --orp <raw_dir,w:h:raw_fmt>,       optional, absolute path of raw files dir \n"
1901                 "                                            raw_fmt: BG10 -> SBGGR10, GB10 -> SGBRG10 \n"
1902                 "                                                     BA10 -> SGRBG10, RG10 -> SRGGB10 \n"
1903                 "         --sensor,  default os04a10,        optional, sensor names\n",
1904                 argv[0]);
1905             exit(-1);
1906 
1907         default:
1908             ERR("?? getopt returned character code 0%o ??\n", c);
1909         }
1910     }
1911 
1912     if (strlen(ctx->dev_name) == 0) {
1913         ERR("%s: arguments --output and --device are required\n", get_sensor_name(ctx));
1914         //exit(-1);
1915     }
1916 
1917 }
1918 
1919 static void deinit(demo_context_t *ctx)
1920 {
1921     //if (!ctx->camgroup_ctx)
1922      stop_capturing(ctx);
1923 
1924     if (ctx->pponeframe)
1925         stop_capturing_pp_oneframe(ctx);
1926     if (ctx->aiq_ctx) {
1927         printf("%s:-------- stop aiq -------------\n", get_sensor_name(ctx));
1928         rk_aiq_uapi2_sysctl_stop(ctx->aiq_ctx, false);
1929     } else if (ctx->camgroup_ctx) {
1930         if (ctx->dev_using == 1) {
1931             printf("%s:-------- stop aiq camgroup -------------\n", get_sensor_name(ctx));
1932             rk_aiq_uapi2_camgroup_stop(ctx->camgroup_ctx);
1933 #ifdef CUSTOM_GROUP_AE_DEMO_TEST
1934             rk_aiq_uapi2_customAE_unRegister((const rk_aiq_sys_ctx_t*)(ctx->camgroup_ctx));
1935 #endif
1936 #ifdef CUSTOM_GROUP_AWB_DEMO_TEST
1937                 rk_aiq_uapi2_customAWB_unRegister((const rk_aiq_sys_ctx_t*)(ctx->camgroup_ctx));
1938 #endif
1939 
1940         }
1941     }
1942 
1943     if (ctx->aiq_ctx) {
1944         printf("%s:-------- deinit aiq -------------\n", get_sensor_name(ctx));
1945 #ifdef CUSTOM_AE_DEMO_TEST
1946         //rk_aiq_AELibunRegCallBack(ctx->aiq_ctx, 0);
1947         rk_aiq_uapi2_customAE_unRegister(ctx->aiq_ctx);
1948 #endif
1949 #ifdef CUSTOM_AWB_DEMO_TEST
1950         //rk_aiq_AELibunRegCallBack(ctx->aiq_ctx, 0);
1951         rk_aiq_uapi2_customAWB_unRegister(ctx->aiq_ctx);
1952 #endif
1953         rk_aiq_uapi2_sysctl_deinit(ctx->aiq_ctx);
1954         printf("%s:-------- deinit aiq end -------------\n", get_sensor_name(ctx));
1955     } else if (ctx->camgroup_ctx) {
1956         if (ctx->dev_using == 1) {
1957             printf("%s:-------- deinit aiq camgroup -------------\n", get_sensor_name(ctx));
1958             rk_aiq_uapi2_camgroup_destroy(ctx->camgroup_ctx);
1959             ctx->camgroup_ctx = NULL;
1960             printf("%s:-------- deinit aiq camgroup end -------------\n", get_sensor_name(ctx));
1961         }
1962     }
1963 
1964 #ifdef ISPFEC_API
1965     rk_ispfec_api_deinit(g_ispfec_ctx);
1966     g_ispfec_ctx = NULL;
1967 #endif
1968 
1969     uninit_device(ctx);
1970     if (ctx->pponeframe)
1971         uninit_device_pp_oneframe(ctx);
1972     close_device(ctx);
1973     if (ctx->pponeframe)
1974         close_device_pp_oneframe(ctx);
1975 
1976     if (ctx->fp)
1977         fclose(ctx->fp);
1978 }
1979 static void signal_handle(int signo)
1980 {
1981     printf("force exit signo %d !!!\n", signo);
1982 
1983     if (g_main_ctx) {
1984         g_main_ctx->frame_count = 0;
1985         stop_capturing(g_main_ctx);
1986         if (g_main_ctx->camGroup && g_second_ctx)
1987             stop_capturing(g_second_ctx);
1988         deinit(g_main_ctx);
1989         g_main_ctx = NULL;
1990     }
1991     if (g_second_ctx) {
1992         g_second_ctx->frame_count = 0;
1993         deinit(g_second_ctx);
1994         g_second_ctx = NULL;
1995     }
1996     exit(0);
1997 }
1998 
1999 static void* test_thread(void* args) {
2000     pthread_detach (pthread_self());
2001     disable_terminal_return();
2002     printf("begin test imgproc\n");
2003     while(!_if_quit) {
2004         // test_imgproc((demo_context_t*) args);
2005         sample_main(args);
2006     }
2007     printf("end test imgproc\n");
2008     restore_terminal_settings();
2009     return 0;
2010 }
2011 
2012 static void* test_offline_thread(void* args) {
2013     pthread_detach (pthread_self());
2014     demo_context_t* demo_ctx = (demo_context_t*) args;
2015     DIR* dir = opendir(demo_ctx->orppath);
2016     struct dirent* dir_ent = NULL;
2017     std::vector<std::string> raw_files;
2018     if (dir) {
2019         while ((dir_ent = readdir(dir))) {
2020             if (dir_ent->d_type == DT_REG) {
2021                 // is raw file
2022                 if (strstr(dir_ent->d_name, ".raw")) {
2023                     raw_files.push_back(dir_ent->d_name);
2024                 }
2025             }
2026         }
2027         closedir(dir);
2028     }
2029     std::sort(raw_files.begin(), raw_files.end(),
2030     [](std::string str1, std::string str2) -> bool {
2031         std::string::size_type sz;
2032         int ind1 = std::stoi(str1, &sz);
2033         int ind2 = std::stoi(str2, &sz);
2034         return ind1 < ind2 ? true : false;
2035     });
2036     while (!demo_ctx->orpStop) {
2037         for (auto raw_file : raw_files) {
2038             std::string full_name = demo_ctx->orppath + raw_file;
2039             printf("process raw : %s \n", full_name.c_str());
2040             rk_aiq_uapi2_sysctl_enqueueRkRawFile(demo_ctx->aiq_ctx, full_name.c_str());
2041             //usleep(500000);
2042         }
2043         usleep(500000);
2044     }
2045     demo_ctx->orpStopped = true;
2046     return 0;
2047 }
2048 
2049 #if 0
2050 static int set_ae_onoff(const rk_aiq_sys_ctx_t* ctx, bool onoff)
2051 {
2052     XCamReturn ret = XCAM_RETURN_NO_ERROR;
2053     Uapi_ExpSwAttr_t expSwAttr;
2054 
2055     ret = rk_aiq_user_api_ae_getExpSwAttr(ctx, &expSwAttr);
2056     expSwAttr.enable = onoff;
2057     ret = rk_aiq_user_api_ae_setExpSwAttr(ctx, expSwAttr);
2058 
2059     return 0;
2060 }
2061 #endif
2062 
2063 static int query_ae_state(const rk_aiq_sys_ctx_t* ctx)
2064 {
2065     XCamReturn ret = XCAM_RETURN_NO_ERROR;
2066     Uapi_ExpQueryInfo_t queryInfo;
2067 
2068     ret =  rk_aiq_user_api2_ae_queryExpResInfo(ctx, &queryInfo);
2069     printf("ae IsConverged: %d\n", queryInfo.IsConverged);
2070 
2071     return 0;
2072 }
2073 
2074 static void set_af_manual_meascfg(const rk_aiq_sys_ctx_t* ctx)
2075 {
2076     rk_aiq_af_attrib_t attr;
2077     uint16_t gamma_y[RKAIQ_RAWAF_GAMMA_NUM] =
2078     {0, 45, 108, 179, 245, 344, 409, 459, 500, 567, 622, 676, 759, 833, 896, 962, 1023};
2079 
2080     rk_aiq_user_api2_af_GetAttrib(ctx, &attr);
2081     attr.AfMode = RKAIQ_AF_MODE_FIXED;
2082 
2083     attr.manual_meascfg.contrast_af_en = 1;
2084     attr.manual_meascfg.rawaf_sel = 0; // normal = 0; hdr = 1
2085 
2086     attr.manual_meascfg.window_num = 2;
2087     attr.manual_meascfg.wina_h_offs = 2;
2088     attr.manual_meascfg.wina_v_offs = 2;
2089     attr.manual_meascfg.wina_h_size = 2580;
2090     attr.manual_meascfg.wina_v_size = 1935;
2091 
2092     attr.manual_meascfg.winb_h_offs = 1146;
2093     attr.manual_meascfg.winb_v_offs = 972;
2094     attr.manual_meascfg.winb_h_size = 300;
2095     attr.manual_meascfg.winb_v_size = 300;
2096 
2097     attr.manual_meascfg.gamma_flt_en = 1;
2098     memcpy(attr.manual_meascfg.gamma_y, gamma_y, RKAIQ_RAWAF_GAMMA_NUM * sizeof(uint16_t));
2099 
2100     attr.manual_meascfg.gaus_flt_en = 1;
2101     attr.manual_meascfg.gaus_h0 = 0x20;
2102     attr.manual_meascfg.gaus_h1 = 0x10;
2103     attr.manual_meascfg.gaus_h2 = 0x08;
2104 
2105     attr.manual_meascfg.afm_thres = 4;
2106 
2107     attr.manual_meascfg.lum_var_shift[0] = 0;
2108     attr.manual_meascfg.afm_var_shift[0] = 0;
2109     attr.manual_meascfg.lum_var_shift[1] = 4;
2110     attr.manual_meascfg.afm_var_shift[1] = 4;
2111 
2112     attr.manual_meascfg.sp_meas.enable = true;
2113     attr.manual_meascfg.sp_meas.ldg_xl = 10;
2114     attr.manual_meascfg.sp_meas.ldg_yl = 28;
2115     attr.manual_meascfg.sp_meas.ldg_kl = (255 - 28) * 256 / 45;
2116     attr.manual_meascfg.sp_meas.ldg_xh = 118;
2117     attr.manual_meascfg.sp_meas.ldg_yh = 8;
2118     attr.manual_meascfg.sp_meas.ldg_kh = (255 - 8) * 256 / 15;
2119     attr.manual_meascfg.sp_meas.highlight_th = 245;
2120     attr.manual_meascfg.sp_meas.highlight2_th = 200;
2121     rk_aiq_user_api2_af_SetAttrib(ctx, &attr);
2122 }
2123 
2124 static void print_af_stats(rk_aiq_isp_stats_t *stats_ref)
2125 {
2126     unsigned long sof_time;
2127 
2128     if (stats_ref->frame_id % 30 != 0)
2129         return;
2130 
2131     sof_time = stats_ref->af_stats.sof_tim / 1000000LL;
2132     printf("sof_tim %ld, sharpness roia: 0x%llx-0x%08x roib: 0x%x-0x%08x\n",
2133            sof_time,
2134            stats_ref->af_stats.roia_sharpness,
2135            stats_ref->af_stats.roia_luminance,
2136            stats_ref->af_stats.roib_sharpness,
2137            stats_ref->af_stats.roib_luminance);
2138 
2139     printf("global_sharpness\n");
2140     for (int i = 0; i < 15; i++) {
2141         for (int j = 0; j < 15; j++) {
2142             printf("0x%08x, ", stats_ref->af_stats.global_sharpness[15 * i + j]);
2143         }
2144         printf("\n");
2145     }
2146     printf("lowpass_fv4_4\n");
2147     for (int i = 0; i < 15; i++) {
2148         for (int j = 0; j < 15; j++) {
2149             printf("0x%08x, ", stats_ref->af_stats.lowpass_fv4_4[15 * i + j]);
2150         }
2151         printf("\n");
2152     }
2153     printf("lowpass_fv8_8\n");
2154     for (int i = 0; i < 15; i++) {
2155         for (int j = 0; j < 15; j++) {
2156             printf("0x%08x, ", stats_ref->af_stats.lowpass_fv8_8[15 * i + j]);
2157         }
2158         printf("\n");
2159     }
2160     printf("lowpass_highlht\n");
2161     for (int i = 0; i < 15; i++) {
2162         for (int j = 0; j < 15; j++) {
2163             printf("0x%08x, ", stats_ref->af_stats.lowpass_highlht[15 * i + j]);
2164         }
2165         printf("\n");
2166     }
2167     printf("lowpass_highlht2\n");
2168     for (int i = 0; i < 15; i++) {
2169         for (int j = 0; j < 15; j++) {
2170             printf("0x%08x, ", stats_ref->af_stats.lowpass_highlht2[15 * i + j]);
2171         }
2172         printf("\n");
2173     }
2174 }
2175 
2176 static void* stats_thread(void* args) {
2177     demo_context_t* ctx =  (demo_context_t*)args;
2178     XCamReturn ret;
2179     pthread_detach (pthread_self());
2180     printf("begin stats thread\n");
2181 
2182     set_af_manual_meascfg(ctx->aiq_ctx);
2183     while(1) {
2184         rk_aiq_isp_stats_t *stats_ref = NULL;
2185         ret = rk_aiq_uapi2_sysctl_get3AStatsBlk(ctx->aiq_ctx, &stats_ref, -1);
2186         if (ret == XCAM_RETURN_NO_ERROR && stats_ref != NULL) {
2187             printf("get one stats frame id %d \n", stats_ref->frame_id);
2188             query_ae_state(ctx->aiq_ctx);
2189             print_af_stats(stats_ref);
2190             rk_aiq_uapi2_sysctl_release3AStatsRef(ctx->aiq_ctx, stats_ref);
2191         } else {
2192             if (ret == XCAM_RETURN_NO_ERROR) {
2193                 printf("aiq has stopped !\n");
2194                 break;
2195             } else if (ret == XCAM_RETURN_ERROR_TIMEOUT) {
2196                 printf("aiq timeout!\n");
2197                 continue;
2198             } else if (ret == XCAM_RETURN_ERROR_FAILED) {
2199                 printf("aiq failed!\n");
2200                 break;
2201             }
2202         }
2203     }
2204     printf("end stats thread\n");
2205     return 0;
2206 }
2207 
2208 void release_buffer(void *addr) {
2209     printf("release buffer called: addr=%p\n", addr);
2210 }
2211 
2212 static void test_tuning_api(demo_context_t *ctx)
2213 {
2214     /*   Sample code of API rk_aiq_uapi2_sysctl_tuning
2215      * This API replaces current iq params through JsonPatch.
2216      * 1. Must be called after Api rk_aiq_uapi2_sysctl_init, prefer to be
2217      * called before rk_aiq_uapi2_sysctl_prepare
2218      * 2. Notice that this API only replaces the current iq params in use, and
2219      * the iq file would not be modified.
2220      *    Supported path including:
2221      * path:/sensor_calib
2222      *       /module_calib
2223      *       And submodules in node 'scene_isp30' , such as
2224      *       /wb_v21  notice that not /main_scene/0/sbu_scene/0/wb_v21, cause
2225      *                there is no scene contex for in-use iq params.
2226      * 'path' could refer to iq json file
2227      * 3.
2228      *  3.1 Prefer to replace the all params of same iq node in one JsonPatch
2229      *  3.2 prefer to replace the params of diffrent iq node in separate JsonPatch
2230      * 4. JsonPatch string format:
2231      *    [// '[' start syntax
2232      *      {  // each 'op' embraced by '{}'
2233               "op": "replace", // Fixed syntax
2234               "path":          // node path in Json iq file
2235               "value":         // Note: All chidren's valuse should be specified for the 'path', otherwise those unspecified ones
2236                                //       may be uninitialzed.
2237      *      }, { //  ',' for next 'op'
2238 
2239      *      } // Note: no ',' for last 'op'
2240      *    ]// ']' end syntax
2241      */
2242     // example 1: replace sensor info
2243     // 1. Show how to repalce the non-leaf node "sensor_calib/resolution"
2244     //    values should be embraced by '{}' for non-leaf node, and all children should be set.
2245     // 2. Show how to replace the values for multiple sub nodes of same parent in one JsonPatch
2246     std::string json_sensor_str = " \n\
2247         [{ \n\
2248             \"op\":\"replace\", \n\
2249             \"path\": \"/sensor_calib/resolution\", \n\
2250             \"value\": \n\
2251             { \"width\": 2222, \"height\": 2160} \n\
2252         }, { \n\
2253             \"op\":\"replace\", \n\
2254             \"path\": \"/sensor_calib/CISFlip\", \n\
2255             \"value\": 6\n\
2256         }]";
2257 
2258     printf("%s\n", json_sensor_str.c_str());
2259     rk_aiq_uapi2_sysctl_tuning(ctx->aiq_ctx, const_cast<char*>(json_sensor_str.c_str()));
2260 
2261     // example 2: replace awb info
2262     // 1. Show how to replace the values for type array
2263     //    value shoulde be embraced by '[]' for type array, and the target
2264     //    length of the array should be unchanged.
2265     // 2. Show how to replace the value for one array item
2266     //    the path for array item is: array name/array index/
2267     std::string json_awb_str = " \n\
2268         [{ \n\
2269             \"op\":\"replace\", \n\
2270             \"path\": \"/wb_v21/autoExtPara/wbGainClip/cct\", \n\
2271             \"value\": \n\
2272             [100,200,300,40,50,60] \n\
2273         },{ \n\
2274             \"op\":\"replace\", \n\
2275             \"path\": \"/wb_v21/autoPara/lightSources/0/name\", \n\
2276             \"value\": \"aaaaaaaaa\" \n\
2277         }]";
2278     printf("%s\n", json_awb_str.c_str());
2279     rk_aiq_uapi2_sysctl_tuning(ctx->aiq_ctx, const_cast<char*>(json_awb_str.c_str()));
2280 
2281     printf("%s done ..\n", __func__);
2282 }
2283 
2284 static void rkisp_routine(demo_context_t *ctx)
2285 {
2286     char sns_entity_name[64];
2287     rk_aiq_working_mode_t work_mode = RK_AIQ_WORKING_MODE_NORMAL;
2288 
2289     if (ctx->hdrmode == 2)
2290         work_mode = RK_AIQ_WORKING_MODE_ISP_HDR2;
2291     else if (ctx->hdrmode == 3)
2292         work_mode = RK_AIQ_WORKING_MODE_ISP_HDR3;
2293 
2294     printf("work_mode %d\n", work_mode);
2295 
2296     strcpy(sns_entity_name, rk_aiq_uapi2_sysctl_getBindedSnsEntNmByVd(get_dev_name(ctx)));
2297     printf("sns_entity_name:%s\n", sns_entity_name);
2298     sscanf(&sns_entity_name[6], "%s", ctx->sns_name);
2299     printf("sns_name:%s\n", ctx->sns_name);
2300     rk_aiq_static_info_t s_info;
2301     rk_aiq_uapi2_sysctl_getStaticMetas(sns_entity_name, &s_info);
2302     // check if hdr mode is supported
2303     if (work_mode != 0) {
2304         bool b_work_mode_supported = false;
2305         rk_aiq_sensor_info_t* sns_info = &s_info.sensor_info;
2306         for (int i = 0; i < SUPPORT_FMT_MAX; i++)
2307             // TODO, should decide the resolution firstly,
2308             // then check if the mode is supported on this
2309             // resolution
2310             if ((sns_info->support_fmt[i].hdr_mode == 5/*HDR_X2*/ &&
2311                     work_mode == RK_AIQ_WORKING_MODE_ISP_HDR2) ||
2312                     (sns_info->support_fmt[i].hdr_mode == 6/*HDR_X3*/ &&
2313                      work_mode == RK_AIQ_WORKING_MODE_ISP_HDR3)) {
2314                 b_work_mode_supported = true;
2315                 break;
2316             }
2317 
2318         if (!b_work_mode_supported) {
2319             printf("\nWARNING !!!"
2320                    "work mode %d is not supported, changed to normal !!!\n\n",
2321                    work_mode);
2322             work_mode = RK_AIQ_WORKING_MODE_NORMAL;
2323         }
2324     }
2325 
2326     printf("%s:-------- open output dev -------------\n", get_sensor_name(ctx));
2327     open_device(ctx);
2328     if (ctx->pponeframe)
2329         open_device_pp_oneframe(ctx);
2330 
2331     if (ctx->writeFile) {
2332         ctx->fp = fopen(ctx->out_file, "w+");
2333         if (ctx->fp == NULL) {
2334             ERR("%s: fopen output file %s failed!\n", get_sensor_name(ctx), ctx->out_file);
2335         }
2336     }
2337 
2338     if (ctx->rkaiq) {
2339         XCamReturn ret = XCAM_RETURN_NO_ERROR;
2340         rk_aiq_tb_info_t tb_info;
2341         tb_info.magic = sizeof(rk_aiq_tb_info_t) - 2;
2342         tb_info.is_pre_aiq = false;
2343         ret = rk_aiq_uapi2_sysctl_preInit_tb_info(sns_entity_name, &tb_info);
2344         if (work_mode == RK_AIQ_WORKING_MODE_NORMAL)
2345             ret = rk_aiq_uapi2_sysctl_preInit_scene(sns_entity_name, "normal", "day");
2346         else
2347             ret = rk_aiq_uapi2_sysctl_preInit_scene(sns_entity_name, "hdr", "day");
2348         if (ret < 0)
2349             ERR("%s: failed to set %s scene\n",
2350                 get_sensor_name(ctx),
2351                 work_mode == RK_AIQ_WORKING_MODE_NORMAL ? "normal" : "hdr");
2352 
2353         if (strlen(ctx->iqpath))
2354         {
2355             if (!ctx->camGroup)
2356                 ctx->aiq_ctx = rk_aiq_uapi2_sysctl_init(sns_entity_name, ctx->iqpath, NULL, NULL);
2357             else {
2358                 // create once for mulitple cams
2359                 if (ctx->dev_using == 1) {
2360                     char sns_entity_name2[64] = {'\0'};
2361                     bool has_dev2 = false;
2362                     if (strlen(ctx->dev_name2)) {
2363                         strcpy(sns_entity_name2, rk_aiq_uapi2_sysctl_getBindedSnsEntNmByVd(ctx->dev_name2));
2364                         printf("sns_entity_name2:%s\n", sns_entity_name2);
2365                         //sscanf(&sns_entity_name2[6], "%s", ctx->sns_name);
2366                         //printf("sns_name2:%s\n", ctx->sns_name);
2367                         has_dev2 = true;
2368                     }
2369 
2370                     rk_aiq_camgroup_instance_cfg_t camgroup_cfg;
2371                     memset(&camgroup_cfg, 0, sizeof(camgroup_cfg));
2372                     camgroup_cfg.sns_num = 1;
2373                     if (has_dev2)
2374                         camgroup_cfg.sns_num++;
2375                     camgroup_cfg.sns_ent_nm_array[0] = sns_entity_name;
2376                     if (has_dev2)
2377                         camgroup_cfg.sns_ent_nm_array[1] = sns_entity_name2;
2378                     camgroup_cfg.config_file_dir = ctx->iqpath;
2379                     camgroup_cfg.overlap_map_file = "srcOverlapMap.bin";
2380                     ctx->camgroup_ctx = rk_aiq_uapi2_camgroup_create(&camgroup_cfg);
2381                     if (!ctx->camgroup_ctx) {
2382                         printf("create camgroup ctx error !\n");
2383                         exit(1);
2384                     }
2385 
2386 #ifdef CUSTOM_GROUP_AE_DEMO_TEST
2387                     rk_aiq_customeAe_cbs_t cbs = {
2388                         .pfn_ae_init = custom_ae_init,
2389                         .pfn_ae_run = custom_ae_run,
2390                         .pfn_ae_ctrl = custom_ae_ctrl,
2391                         .pfn_ae_exit = custom_ae_exit,
2392                     };
2393                     rk_aiq_uapi2_customAE_register((const rk_aiq_sys_ctx_t*)(ctx->camgroup_ctx), &cbs);
2394                     rk_aiq_uapi2_customAE_enable((const rk_aiq_sys_ctx_t*)(ctx->camgroup_ctx), true);
2395 #endif
2396 #ifdef CUSTOM_GROUP_AWB_DEMO_TEST
2397                 rk_aiq_customeAwb_cbs_t awb_cbs = {
2398                     .pfn_awb_init = custom_awb_init,
2399                     .pfn_awb_run = custom_awb_run,
2400                     .pfn_awb_ctrl= custom_awb_ctrl,
2401                     .pfn_awb_exit = custom_awb_exit,
2402                 };
2403                 rk_aiq_uapi2_customAWB_register((const rk_aiq_sys_ctx_t*)(ctx->camgroup_ctx), &awb_cbs);
2404                 rk_aiq_uapi2_customAWB_enable((const rk_aiq_sys_ctx_t*)(ctx->camgroup_ctx), true);
2405 #endif
2406 
2407                 }
2408             }
2409         } else {
2410             if (ctx->camGroup) {
2411                 printf("error! should specify iq path !\n");
2412                 exit(1);
2413             }
2414 #ifndef ANDROID
2415             rk_aiq_uapi2_sysctl_preInit(sns_entity_name, RK_AIQ_WORKING_MODE_NORMAL, "ov5695_TongJu_CHT842-MD.xml");
2416             ctx->aiq_ctx = rk_aiq_uapi2_sysctl_init(sns_entity_name, "/oem/etc/iqfiles", NULL, NULL);
2417 #else
2418             ctx->aiq_ctx = rk_aiq_uapi2_sysctl_init(sns_entity_name, "/data/etc/iqfiles", NULL, NULL);
2419 #endif
2420 
2421         }
2422         if (ctx->aiq_ctx) {
2423             printf("%s:-------- init mipi tx/rx -------------\n", get_sensor_name(ctx));
2424             if (ctx->writeFileSync)
2425                 rk_aiq_uapi2_debug_captureRawYuvSync(ctx->aiq_ctx, CAPTURE_RAW_AND_YUV_SYNC);
2426 #ifdef CUSTOM_AE_DEMO_TEST
2427             //ae_reg.stAeExpFunc.pfn_ae_init = ae_init;
2428             //ae_reg.stAeExpFunc.pfn_ae_run = ae_run;
2429             //ae_reg.stAeExpFunc.pfn_ae_ctrl = ae_ctrl;
2430             //ae_reg.stAeExpFunc.pfn_ae_exit = ae_exit;
2431             //rk_aiq_AELibRegCallBack(ctx->aiq_ctx, &ae_reg, 0);
2432             rk_aiq_customeAe_cbs_t cbs = {
2433                 .pfn_ae_init = custom_ae_init,
2434                 .pfn_ae_run = custom_ae_run,
2435                 .pfn_ae_ctrl = custom_ae_ctrl,
2436                 .pfn_ae_exit = custom_ae_exit,
2437             };
2438             rk_aiq_uapi2_customAE_register(ctx->aiq_ctx, &cbs);
2439             rk_aiq_uapi2_customAE_enable(ctx->aiq_ctx, true);
2440 #endif
2441 #ifdef CUSTOM_AWB_DEMO_TEST
2442             rk_aiq_customeAwb_cbs_t awb_cbs = {
2443                 .pfn_awb_init = custom_awb_init,
2444                 .pfn_awb_run = custom_awb_run,
2445                 .pfn_awb_ctrl = custom_awb_ctrl,
2446                 .pfn_awb_exit = custom_awb_exit,
2447             };
2448             rk_aiq_uapi2_customAWB_register(ctx->aiq_ctx, &awb_cbs);
2449             rk_aiq_uapi2_customAWB_enable(ctx->aiq_ctx, true);
2450 #endif
2451             if (ctx->isOrp) {
2452                 rk_aiq_raw_prop_t prop;
2453                 if (strcmp(ctx->orpRawFmt, "BA81") == 0)
2454                     prop.format = RK_PIX_FMT_SBGGR8;
2455                 else if (strcmp(ctx->orpRawFmt, "GBRG") == 0)
2456                     prop.format = RK_PIX_FMT_SGBRG8;
2457                 else if (strcmp(ctx->orpRawFmt, "RGGB") == 0)
2458                     prop.format = RK_PIX_FMT_SRGGB8;
2459                 else if (strcmp(ctx->orpRawFmt, "GRBG") == 0)
2460                     prop.format = RK_PIX_FMT_SGRBG8;
2461                 else if (strcmp(ctx->orpRawFmt, "BG10") == 0)
2462                     prop.format = RK_PIX_FMT_SBGGR10;
2463                 else if (strcmp(ctx->orpRawFmt, "GB10") == 0)
2464                     prop.format = RK_PIX_FMT_SGBRG10;
2465                 else if (strcmp(ctx->orpRawFmt, "RG10") == 0)
2466                     prop.format = RK_PIX_FMT_SRGGB10;
2467                 else if (strcmp(ctx->orpRawFmt, "BA10") == 0)
2468                     prop.format = RK_PIX_FMT_SGRBG10;
2469                 else if (strcmp(ctx->orpRawFmt, "BG12") == 0)
2470                     prop.format = RK_PIX_FMT_SBGGR12;
2471                 else if (strcmp(ctx->orpRawFmt, "GB12") == 0)
2472                     prop.format = RK_PIX_FMT_SGBRG12;
2473                 else if (strcmp(ctx->orpRawFmt, "RG12") == 0)
2474                     prop.format = RK_PIX_FMT_SRGGB12;
2475                 else if (strcmp(ctx->orpRawFmt, "BA12") == 0)
2476                     prop.format = RK_PIX_FMT_SGRBG12;
2477                 else if (strcmp(ctx->orpRawFmt, "BG14") == 0)
2478                     prop.format = RK_PIX_FMT_SBGGR14;
2479                 else if (strcmp(ctx->orpRawFmt, "GB14") == 0)
2480                     prop.format = RK_PIX_FMT_SGBRG14;
2481                 else if (strcmp(ctx->orpRawFmt, "RG14") == 0)
2482                     prop.format = RK_PIX_FMT_SRGGB14;
2483                 else if (strcmp(ctx->orpRawFmt, "BA14") == 0)
2484                     prop.format = RK_PIX_FMT_SGRBG14;
2485                 else
2486                     prop.format = RK_PIX_FMT_SBGGR10;
2487                 prop.frame_width = ctx->orpRawW;
2488                 prop.frame_height = ctx->orpRawH;
2489                 prop.rawbuf_type = RK_AIQ_RAW_FILE;
2490                 rk_aiq_uapi2_sysctl_prepareRkRaw(ctx->aiq_ctx, prop);
2491             }
2492             /*
2493              * rk_aiq_uapi_setFecEn(ctx->aiq_ctx, true);
2494              * rk_aiq_uapi_setFecCorrectDirection(ctx->aiq_ctx, FEC_CORRECT_DIRECTION_Y);
2495              */
2496 #ifdef TEST_MEMS_SENSOR_INTF
2497             rk_aiq_mems_sensor_intf_t g_rkiio_aiq_api;
2498             rk_aiq_uapi2_sysctl_regMemsSensorIntf(ctx->aiq_ctx, &g_rkiio_aiq_api);
2499 #endif
2500 
2501 #if 0
2502             test_tuning_api(ctx);
2503 #endif
2504             XCamReturn ret = rk_aiq_uapi2_sysctl_prepare(ctx->aiq_ctx, ctx->width, ctx->height, work_mode);
2505 
2506             if (ret != XCAM_RETURN_NO_ERROR)
2507                 ERR("%s:rk_aiq_uapi2_sysctl_prepare failed: %d\n", get_sensor_name(ctx), ret);
2508             else {
2509                 ret = rk_aiq_uapi2_setMirrorFlip(ctx->aiq_ctx, false, false, 3);
2510                 // Ignore failure
2511 
2512                 if (ctx->isOrp) {
2513                     rk_aiq_uapi2_sysctl_registRkRawCb(ctx->aiq_ctx, release_buffer);
2514                 }
2515                 ret = rk_aiq_uapi2_sysctl_start(ctx->aiq_ctx );
2516 
2517                 init_device(ctx);
2518                 if (ctx->pponeframe)
2519                     init_device_pp_oneframe(ctx);
2520                 if (ctx->ctl_type == TEST_CTL_TYPE_DEFAULT) {
2521                     start_capturing(ctx);
2522                 }
2523                 if (ctx->pponeframe)
2524                     start_capturing_pp_oneframe(ctx);
2525                 printf("%s:-------- stream on mipi tx/rx -------------\n", get_sensor_name(ctx));
2526 
2527                 if (ctx->ctl_type != TEST_CTL_TYPE_DEFAULT) {
2528 restart:
2529                     static int test_ctl_cnts = 0;
2530                     ctx->frame_count = 60;
2531                     start_capturing(ctx);
2532                     while ((ctx->frame_count-- > 0))
2533                         read_frame(ctx);
2534                     stop_capturing(ctx);
2535                     printf("+++++++ TEST SYSCTL COUNTS %d ++++++++++++ \n", test_ctl_cnts++);
2536                     printf("aiq stop .....\n");
2537                     rk_aiq_uapi2_sysctl_stop(ctx->aiq_ctx, false);
2538                     if (ctx->ctl_type == TEST_CTL_TYPE_REPEAT_INIT_PREPARE_START_STOP_DEINIT) {
2539                         printf("aiq deinit .....\n");
2540                         rk_aiq_uapi2_sysctl_deinit(ctx->aiq_ctx);
2541                         printf("aiq init .....\n");
2542                         if (work_mode == RK_AIQ_WORKING_MODE_NORMAL) {
2543                             ret = rk_aiq_uapi2_sysctl_preInit_scene(sns_entity_name, "normal", "day");
2544                             if (ctx->hdrmode == 2)
2545                                 work_mode = RK_AIQ_WORKING_MODE_ISP_HDR2;
2546                             else if (ctx->hdrmode == 3)
2547                                 work_mode = RK_AIQ_WORKING_MODE_ISP_HDR3;
2548                         } else {
2549                             ret = rk_aiq_uapi2_sysctl_preInit_scene(sns_entity_name, "hdr", "day");
2550                             work_mode = RK_AIQ_WORKING_MODE_NORMAL;
2551                         }
2552                         if (ret < 0)
2553                             ERR("%s: failed to set %s scene\n",
2554                                 get_sensor_name(ctx),
2555                                 work_mode == RK_AIQ_WORKING_MODE_NORMAL ? "normal" : "hdr");
2556                         ctx->aiq_ctx = rk_aiq_uapi2_sysctl_init(sns_entity_name, ctx->iqpath, NULL, NULL);
2557                         printf("aiq prepare .....\n");
2558                         XCamReturn ret = rk_aiq_uapi2_sysctl_prepare(ctx->aiq_ctx, ctx->width, ctx->height, work_mode);
2559                     } else if (ctx->ctl_type == TEST_CTL_TYPE_REPEAT_PREPARE_START_STOP) {
2560                         printf("aiq prepare .....\n");
2561                         XCamReturn ret = rk_aiq_uapi2_sysctl_prepare(ctx->aiq_ctx, ctx->width, ctx->height, work_mode);
2562                     } else if (ctx->ctl_type == TEST_CTL_TYPE_REPEAT_START_STOP) {
2563                         // do nothing
2564                     }
2565                     printf("aiq start .....\n");
2566                     ret = rk_aiq_uapi2_sysctl_start(ctx->aiq_ctx );
2567                     printf("aiq restart .....\n");
2568                     goto restart;
2569                 }
2570             }
2571 
2572         } else if (ctx->camgroup_ctx) {
2573             // only do once for cam group
2574             if (ctx->dev_using == 1) {
2575                 XCamReturn ret = rk_aiq_uapi2_camgroup_prepare(ctx->camgroup_ctx, work_mode);
2576 
2577                 if (ret != XCAM_RETURN_NO_ERROR)
2578                     ERR("%s:rk_aiq_uapi2_camgroup_prepare failed: %d\n", get_sensor_name(ctx), ret);
2579                 else {
2580 
2581                     ret = rk_aiq_uapi2_camgroup_start(ctx->camgroup_ctx);
2582                 }
2583             }
2584             init_device(ctx);
2585             start_capturing(ctx);
2586         }
2587     }
2588     else {
2589         init_device(ctx);
2590         if (ctx->pponeframe)
2591             init_device_pp_oneframe(ctx);
2592         start_capturing(ctx);
2593         if (ctx->pponeframe)
2594             start_capturing_pp_oneframe(ctx);
2595     }
2596 }
2597 
2598 static void* others_thread(void* args) {
2599     pthread_detach (pthread_self());
2600     demo_context_t* ctx = (demo_context_t*) args;
2601     rkisp_routine(ctx);
2602     mainloop(ctx);
2603     deinit(ctx);
2604     return 0;
2605 }
2606 
2607 int main(int argc, char **argv)
2608 {
2609 #ifdef _WIN32
2610     signal (SIGINT, signal_handle);
2611     signal (SIGQUIT, signal_handle);
2612     signal (SIGTERM, signal_handle);
2613 #else
2614     sigset_t mask;
2615     sigemptyset(&mask);
2616     sigaddset(&mask, SIGINT);
2617     sigaddset(&mask, SIGTERM);
2618     sigaddset(&mask, SIGQUIT);
2619     pthread_sigmask(SIG_BLOCK, &mask, NULL);
2620 
2621     struct sigaction new_action, old_action;
2622     new_action.sa_handler = signal_handle;
2623     sigemptyset (&new_action.sa_mask);
2624     new_action.sa_flags = 0;
2625     sigaction (SIGINT, NULL, &old_action);
2626     if (old_action.sa_handler != SIG_IGN)
2627         sigaction (SIGINT, &new_action, NULL);
2628     sigaction (SIGQUIT, NULL, &old_action);
2629     if (old_action.sa_handler != SIG_IGN)
2630         sigaction (SIGQUIT, &new_action, NULL);
2631     sigaction (SIGTERM, NULL, &old_action);
2632     if (old_action.sa_handler != SIG_IGN)
2633         sigaction (SIGTERM, &new_action, NULL);
2634 #endif
2635 
2636 
2637     demo_context_t main_ctx = {
2638         .out_file = {'\0'},
2639         .dev_name = {'\0'},
2640         .dev_name2 = {'\0'},
2641         .dev_name3 = {'\0'},
2642         .dev_name4 = {'\0'},
2643         .sns_name = {'\0'},
2644         .dev_using = 1,
2645         .width = 640,
2646         .height = 480,
2647         .format = V4L2_PIX_FMT_NV12,
2648         .fd = -1,
2649         .buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
2650         .buffers = NULL,
2651         .n_buffers = 0,
2652         .frame_count = -1,
2653         .fp = NULL,
2654         .aiq_ctx = NULL,
2655         .camgroup_ctx = NULL,
2656         .vop = 0,
2657         .rkaiq = 0,
2658         .writeFile = 0,
2659         .writeFileSync = 0,
2660         .pponeframe = 0,
2661         .hdrmode = 0,
2662         .limit_range = 0,
2663         .fd_pp_input = -1,
2664         .fd_isp_mp = -1,
2665         .buffers_mp = NULL,
2666         .outputCnt = 3,
2667         .skipCnt = 30,
2668         .yuv_dir_path = {'\0'},
2669         ._is_yuv_dir_exist = false,
2670         .capture_yuv_num = 0,
2671         .is_capture_yuv = false,
2672         .ctl_type = TEST_CTL_TYPE_DEFAULT,
2673         .iqpath = {'\0'},
2674         .orppath = {'\0'},
2675         .orpRawW = 0,
2676         .orpRawH = 0,
2677         .orpRawFmt = {'\0'},
2678         .isOrp = false,
2679         .orpStop = false,
2680         .orpStopped = false,
2681         .camGroup = false,
2682     };
2683     demo_context_t second_ctx;
2684     demo_context_t third_ctx;
2685     demo_context_t fourth_ctx;
2686 
2687     parse_args(argc, argv, &main_ctx);
2688 
2689 #if ISPDEMO_ENABLE_DRM
2690     if (main_ctx.vop) {
2691 
2692 #if ISPDEMO_ENABLE_RGA
2693         if (strlen(main_ctx.dev_name) && strlen(main_ctx.dev_name2)) {
2694             if (display_init(720, 1280) < 0) {
2695                 printf("display_init failed\n");
2696             }
2697         } else {
2698 #else
2699         {
2700 #endif
2701             if (initDrmDsp() < 0) {
2702                 printf("initDrmDsp failed\n");
2703             }
2704         }
2705     }
2706 #endif
2707 
2708     rkisp_routine(&main_ctx);
2709     g_main_ctx = &main_ctx;
2710 
2711     if(strlen(main_ctx.dev_name2)) {
2712         pthread_t sec_tid;
2713         second_ctx = main_ctx;
2714         second_ctx.dev_using = 2;
2715         g_second_ctx = &second_ctx;
2716         pthread_create(&sec_tid, NULL, others_thread, &second_ctx);
2717     }
2718 
2719     if(strlen(main_ctx.dev_name3)) {
2720         pthread_t thr_tid;
2721         third_ctx = main_ctx;
2722         third_ctx.dev_using = 3;
2723         g_third_ctx = &third_ctx;
2724         pthread_create(&thr_tid, NULL, others_thread, &third_ctx);
2725     }
2726 
2727     if(strlen(main_ctx.dev_name4)) {
2728         pthread_t fou_tid;
2729         fourth_ctx = main_ctx;
2730         fourth_ctx.dev_using = 4;
2731         g_fourth_ctx = &fourth_ctx;
2732         pthread_create(&fou_tid, NULL, others_thread, &fourth_ctx);
2733     }
2734 
2735 #ifdef ENABLE_UAPI_TEST
2736     pthread_t tid;
2737     pthread_create(&tid, NULL, test_thread, &main_ctx);
2738 #endif
2739 
2740     if (main_ctx.isOrp) {
2741         pthread_t tid_offline;
2742         pthread_create(&tid_offline, NULL, test_offline_thread, &main_ctx);
2743     }
2744 
2745 //#define TEST_BLOCKED_STATS_FUNC
2746 #ifdef TEST_BLOCKED_STATS_FUNC
2747     pthread_t stats_tid;
2748     pthread_create(&stats_tid, NULL, stats_thread, &main_ctx);
2749 #endif
2750 #ifdef CUSTOM_AF_DEMO_TEST
2751     custom_af_run(main_ctx.aiq_ctx);
2752 #endif
2753 
2754 #ifdef ISPFEC_API
2755     g_ispfec_cfg.in_width     = main_ctx.width;
2756     g_ispfec_cfg.in_height    = main_ctx.height;
2757     g_ispfec_cfg.out_width     = main_ctx.width;
2758     g_ispfec_cfg.out_height    = main_ctx.height;
2759     g_ispfec_cfg.in_fourcc = 0;
2760     g_ispfec_cfg.out_fourcc = 0;
2761 #if 1
2762     g_ispfec_cfg.mesh_upd_mode = RK_ISPFEC_UPDATE_MESH_FROM_FILE;
2763     strcpy(g_ispfec_cfg.u.mesh_file_path, "/etc/iqfiles/FEC_mesh_3840_2160_imx415_3.6mm/");
2764     strcpy(g_ispfec_cfg.mesh_xint.mesh_file, "meshxi_level0.bin");
2765     strcpy(g_ispfec_cfg.mesh_xfra.mesh_file, "meshxf_level0.bin");
2766     strcpy(g_ispfec_cfg.mesh_yint.mesh_file, "meshyi_level0.bin");
2767     strcpy(g_ispfec_cfg.mesh_yfra.mesh_file, "meshyf_level0.bin");
2768 #else
2769     g_ispfec_cfg.mesh_upd_mode = RK_ISPFEC_UPDATE_MESH_ONLINE;
2770     g_ispfec_cfg.u.mesh_online.light_center[0] = 1956.3909119999998438;
2771     g_ispfec_cfg.u.mesh_online.light_center[1] = 1140.6355200000000422;
2772     g_ispfec_cfg.u.mesh_online.coeff[0] = -2819.4072493821618081;
2773     g_ispfec_cfg.u.mesh_online.coeff[1] = 0.0000316126581792;
2774     g_ispfec_cfg.u.mesh_online.coeff[2] = 0.0000000688410142;
2775     g_ispfec_cfg.u.mesh_online.coeff[3] = -0.0000000000130686;
2776     g_ispfec_cfg.u.mesh_online.correct_level = 250;
2777     g_ispfec_cfg.u.mesh_online.direction = RK_ISPFEC_CORRECT_DIRECTION_XY;
2778     g_ispfec_cfg.u.mesh_online.style = RK_ISPFEC_KEEP_ASPECT_RATIO_REDUCE_FOV;
2779 #endif
2780     init_ispfec_bufs(&g_ispfec_cfg);
2781     g_ispfec_ctx = rk_ispfec_api_init(&g_ispfec_cfg);
2782 #endif
2783 
2784     pthread_sigmask(SIG_UNBLOCK, &mask, NULL);
2785 
2786     mainloop(&main_ctx);
2787     if (main_ctx.isOrp) {
2788         main_ctx.orpStop = true;
2789         while (!main_ctx.orpStopped) {
2790             printf("wait orp stopped ... \n");
2791             usleep(500000);
2792         }
2793     }
2794     deinit(&main_ctx);
2795 
2796 #if ISPDEMO_ENABLE_DRM
2797 #if ISPDEMO_ENABLE_RGA
2798     if (strlen(main_ctx.dev_name) && strlen(main_ctx.dev_name2)) {
2799         display_exit();
2800     }
2801 #endif
2802     deInitDrmDsp();
2803 #endif
2804     return 0;
2805 }
2806 
2807