sipeed / LicheeRV-Nano-Build

LicheeRV-Nano-Build
103 stars 39 forks source link

sensor_test样例输出的yuv文件颜色错误 #22

Closed 981213 closed 5 months ago

981213 commented 5 months ago

如题。

样例代码在SAMPLE_COMM_VI_IniToViCfg中, https://github.com/sipeed/LicheeRV-Nano-Build/blob/main/middleware/v2/sample/common/sample_common_vi.c#L1040 一行定义的图像格式为VI_PIXEL_FORMAT,即PIXEL_FORMAT_NV21。 但是运行sensor_test样例使用dump_yuv功能,或者根据该样例简化得到如下代码:

测试代码 ```c #include #include #include static SAMPLE_VI_CONFIG_S g_stViConfig; static SAMPLE_INI_CFG_S g_stIniCfg; static int sys_vi_init(void) { MMF_VERSION_S stVersion; SAMPLE_INI_CFG_S stIniCfg; SAMPLE_VI_CONFIG_S stViConfig; PIC_SIZE_E enPicSize; SIZE_S stSize; CVI_S32 s32Ret = CVI_SUCCESS; LOG_LEVEL_CONF_S log_conf; CVI_SYS_GetVersion(&stVersion); SAMPLE_PRT("MMF Version:%s\n", stVersion.version); log_conf.enModId = CVI_ID_LOG; log_conf.s32Level = CVI_DBG_INFO; CVI_LOG_SetLevelConf(&log_conf); // Get config from ini if found. if (SAMPLE_COMM_VI_ParseIni(&stIniCfg)) { SAMPLE_PRT("Parse complete\n"); } //Set sensor number CVI_VI_SetDevNum(stIniCfg.devNum); /************************************************ * step1: Config VI ************************************************/ s32Ret = SAMPLE_COMM_VI_IniToViCfg(&stIniCfg, &stViConfig); if (s32Ret != CVI_SUCCESS) return s32Ret; memcpy(&g_stViConfig, &stViConfig, sizeof(SAMPLE_VI_CONFIG_S)); memcpy(&g_stIniCfg, &stIniCfg, sizeof(SAMPLE_INI_CFG_S)); /************************************************ * step2: Get input size ************************************************/ s32Ret = SAMPLE_COMM_VI_GetSizeBySensor(stIniCfg.enSnsType[0], &enPicSize); if (s32Ret != CVI_SUCCESS) { CVI_TRACE_LOG(CVI_DBG_ERR, "SAMPLE_COMM_VI_GetSizeBySensor failed with %#x\n", s32Ret); return s32Ret; } s32Ret = SAMPLE_COMM_SYS_GetPicSize(enPicSize, &stSize); if (s32Ret != CVI_SUCCESS) { CVI_TRACE_LOG(CVI_DBG_ERR, "SAMPLE_COMM_SYS_GetPicSize failed with %#x\n", s32Ret); return s32Ret; } /************************************************ * step3: Init modules ************************************************/ s32Ret = SAMPLE_PLAT_SYS_INIT(stSize); if (s32Ret != CVI_SUCCESS) { CVI_TRACE_LOG(CVI_DBG_ERR, "sys init failed. s32Ret: 0x%x !\n", s32Ret); return s32Ret; } s32Ret = SAMPLE_PLAT_VI_INIT(&stViConfig); if (s32Ret != CVI_SUCCESS) { CVI_TRACE_LOG(CVI_DBG_ERR, "vi init failed. s32Ret: 0x%x !\n", s32Ret); return s32Ret; } return CVI_SUCCESS; } static void sys_vi_deinit(void) { SAMPLE_COMM_VI_DestroyIsp(&g_stViConfig); SAMPLE_COMM_VI_DestroyVi(&g_stViConfig); SAMPLE_COMM_SYS_Exit(); } static CVI_S32 _vi_get_chn_frame(CVI_U8 chn) { VIDEO_FRAME_INFO_S stVideoFrame; VI_CROP_INFO_S crop_info = {0}; if (CVI_VI_GetChnFrame(0, chn, &stVideoFrame, 3000) == 0) { FILE *output; size_t image_size = stVideoFrame.stVFrame.u32Length[0] + stVideoFrame.stVFrame.u32Length[1] + stVideoFrame.stVFrame.u32Length[2]; CVI_VOID *vir_addr; CVI_U32 plane_offset, u32LumaSize, u32ChromaSize; CVI_CHAR img_name[128] = {0, }; CVI_TRACE_LOG(CVI_DBG_WARN, "width: %d, height: %d, total_buf_length: %zu\n", stVideoFrame.stVFrame.u32Width, stVideoFrame.stVFrame.u32Height, image_size); snprintf(img_name, sizeof(img_name), "sample_%d.yuv", chn); output = fopen(img_name, "wb"); if (output == NULL) { memset(img_name, 0x0, sizeof(img_name)); snprintf(img_name, sizeof(img_name), "/mnt/data/sample_%d.yuv", chn); output = fopen(img_name, "wb"); if (output == NULL) { CVI_VI_ReleaseChnFrame(0, chn, &stVideoFrame); CVI_TRACE_LOG(CVI_DBG_ERR, "fopen fail\n"); return CVI_FAILURE; } } u32LumaSize = stVideoFrame.stVFrame.u32Stride[0] * stVideoFrame.stVFrame.u32Height; u32ChromaSize = stVideoFrame.stVFrame.u32Stride[1] * stVideoFrame.stVFrame.u32Height / 2; CVI_VI_GetChnCrop(0, chn, &crop_info); if (crop_info.bEnable) { u32LumaSize = ALIGN((crop_info.stCropRect.u32Width * 8 + 7) >> 3, DEFAULT_ALIGN) * ALIGN(crop_info.stCropRect.u32Height, 2); u32ChromaSize = (ALIGN(((crop_info.stCropRect.u32Width >> 1) * 8 + 7) >> 3, DEFAULT_ALIGN) * ALIGN(crop_info.stCropRect.u32Height, 2)) >> 1; } vir_addr = CVI_SYS_Mmap(stVideoFrame.stVFrame.u64PhyAddr[0], image_size); CVI_SYS_IonInvalidateCache(stVideoFrame.stVFrame.u64PhyAddr[0], vir_addr, image_size); plane_offset = 0; for (int i = 0; i < 3; i++) { if (stVideoFrame.stVFrame.u32Length[i] != 0) { stVideoFrame.stVFrame.pu8VirAddr[i] = vir_addr + plane_offset; plane_offset += stVideoFrame.stVFrame.u32Length[i]; CVI_TRACE_LOG(CVI_DBG_WARN, "plane(%d): paddr(%#lld) vaddr(%p) stride(%d) length(%d)\n", i, stVideoFrame.stVFrame.u64PhyAddr[i], stVideoFrame.stVFrame.pu8VirAddr[i], stVideoFrame.stVFrame.u32Stride[i], stVideoFrame.stVFrame.u32Length[i]); fwrite((void *)stVideoFrame.stVFrame.pu8VirAddr[i] , (i == 0) ? u32LumaSize : u32ChromaSize, 1, output); } } CVI_SYS_Munmap(vir_addr, image_size); if (CVI_VI_ReleaseChnFrame(0, chn, &stVideoFrame) != 0) CVI_TRACE_LOG(CVI_DBG_ERR, "CVI_VI_ReleaseChnFrame NG\n"); fclose(output); return CVI_SUCCESS; } CVI_TRACE_LOG(CVI_DBG_ERR, "CVI_VI_GetChnFrame NG\n"); return CVI_FAILURE; } static CVI_S32 sensor_dump_yuv(void) { CVI_S32 loop = 0; CVI_U32 ok = 0, ng = 0; CVI_U8 chn = 0; int tmp; struct timespec start, end; chn = 0; loop = 5; while (loop > 0) { if (_vi_get_chn_frame(chn) == CVI_SUCCESS) { ++ok; } else ++ng; //sleep(1); if (loop != 11111) loop--; } CVI_TRACE_LOG(CVI_DBG_WARN, "VI GetChnFrame OK(%d) NG(%d)\n", ok, ng); CVI_TRACE_LOG(CVI_DBG_WARN, "Dump VI yuv TEST-PASS\n"); return CVI_SUCCESS; } int main() { sys_vi_init(); sensor_dump_yuv(); sys_vi_deinit(); return 0; } ```

实际输出的图像按照NV21打开,颜色错误。 硬件为LicheeRV Nano 量产版本,软件为当前git最新版本。

981213 commented 5 months ago

屏幕截图_20240523_165842 附图,图为按nv21打开的效果

981213 commented 5 months ago

不对,是红蓝反了,不是UV反了。

lxowalle commented 5 months ago

发一下完整的日志和抓出来的图

981213 commented 5 months ago
sensor_test日志 ``` # sensor_test [sys_vi_init]-41: MMF Version:e4c87a6db-musl_riscv64 [SAMPLE_COMM_SNS_ParseIni]-2166: Parse /mnt/data/sensor_cfg.ini [parse_source_devnum]-1759: devNum = 1 [parse_sensor_name]-1840: sensor = GCORE_GC4653_MIPI_4M_30FPS_10BIT [parse_sensor_busid]-1869: bus_id = 4 [parse_sensor_i2caddr]-1880: sns_i2c_addr = 29 [parse_sensor_mipidev]-1891: mipi_dev = 0 [parse_sensor_laneid]-1902: Lane_id = 4, 3, 2, -1, -1 [parse_sensor_pnswap]-1913: pn_swap = 0, 0, 0, 0, 0 [parse_sensor_mclken]-1935: mclk_en = 1 [parse_sensor_mclk]-1946: mclk = 1 [SAMPLE_PLAT_SYS_INIT]-72: common pool[0] BlkSize 5652480 ISP Vipipe(0) Allocate pa(0x8de20000) va(0x0x3fd52c1000) size(291424) stSnsrMode.u16Width 2560 stSnsrMode.u16Height 1440 25.000000 wdrMode 0 pstSnsObj 0xebad0 [SAMPLE_COMM_VI_StartMIPI]-494: sensor 0 stDevAttr.devno 0 awbInit ver 6.9@2021500 0 R:1400 B:3100 CT:2850 1 R:1500 B:2500 CT:3900 2 R:2300 B:1600 CT:6500 Golden 1024 1024 1024 WB Quadratic:0 isWdr:0 ViPipe:0,===GC4653 1440P 30fps 10bit LINEAR Init OK!=== ******************************************************************************** cvi_bin_isp message gerritId: 97347 commitId: fc6ce647 md5: d6db2297ddfd44e8252c1f3f888f47b2 sensorNum 1 sensorName0 4653 PQBIN message gerritId: commitId: fc6ce647 md5: d6db2297ddfd44e8252c1f3f888f47b2 sensorNum 1 sensorName0 4653 author: lxowalle desc: gc4653 30fps createTime: 2024-03-26 13:41:34version: tool Version: v3.0.5.48 mode: ******************************************************************************** [SAMPLE_COMM_ISP_Thread]-95: ISP Dev 0 running! 0 R:1298 B:3773 CT:2688 1 R:1629 B:2599 CT:3890 2 R:2430 B:1675 CT:7300 Golden 1629 1024 2599 wdrLEOnly:1 [main]-538: ---Basic------------------------------------------------ [main]-539: 1: dump vi raw frame [main]-540: 2: dump vi yuv frame [main]-541: 3: set chn flip/mirror [main]-542: 4: linear wdr switch [main]-543: 5: AE debug [main]-544: 6: sensor dump [main]-545: 7: sensor proc [main]-546: 255: exit 2 0 2 [main]-538: ---Basic------------------------------------------------ [main]-539: 1: dump vi raw frame [main]-540: 2: dump vi yuv frame [main]-541: 3: set chn flip/mirror [main]-542: 4: linear wdr switch [main]-543: 5: AE debug [main]-544: 6: sensor dump [main]-545: 7: sensor proc [main]-546: 255: exit 255 ISP Vipipe(0) Free pa(0x8de20000) va(0x0x3fd52c1000) ```

输出yuv文件

sample_0.yuv.zip

981213 commented 5 months ago

有的日志写在syslog里面了

Jan  1 00:00:35 licheervnano-7dc2 local5.warn : [SYS-WRN] sample_common_bin.c:36:SAMPLE_COMM_BIN_ReadParaFrombin(): Bin exist (/mnt/cfg/param/cvi_sdr_bin)
Jan  1 00:00:37 licheervnano-7dc2 auth.err getty[521]: can't open '/dev/ttyGS0': No such file or directory^M
Jan  1 00:00:39 licheervnano-7dc2 local5.warn : [LOG-WRN] sensor_test.c:236:sensor_dump_yuv(): Get frm from which chn(0~1): 
Jan  1 00:00:41 licheervnano-7dc2 local5.warn : [LOG-WRN] sensor_test.c:239:sensor_dump_yuv(): how many loops to do(11111 is infinite: 
Jan  1 00:00:42 licheervnano-7dc2 local5.warn : [LOG-WRN] sensor_test.c:119:_vi_get_chn_frame(): width: 2560, height: 1440, total_buf_length: 5529600
Jan  1 00:00:42 licheervnano-7dc2 local5.warn : [LOG-WRN] sensor_test.c:153:_vi_get_chn_frame(): plane(0): paddr(0x8d358000) vaddr(0x3fd4bf6000) stride(2560) length(3686400)
Jan  1 00:00:42 licheervnano-7dc2 local5.warn : [LOG-WRN] sensor_test.c:153:_vi_get_chn_frame(): plane(1): paddr(0x8d6dc000) vaddr(0x3fd4f7a000) stride(2560) length(1843200)
Jan  1 00:00:42 licheervnano-7dc2 local5.warn : [LOG-WRN] sensor_test.c:246:sensor_dump_yuv(): ms consumed: 290.471985
Jan  1 00:00:42 licheervnano-7dc2 local5.warn : [LOG-WRN] sensor_test.c:119:_vi_get_chn_frame(): width: 2560, height: 1440, total_buf_length: 5529600
Jan  1 00:00:42 licheervnano-7dc2 local5.warn : [LOG-WRN] sensor_test.c:153:_vi_get_chn_frame(): plane(0): paddr(0x8d8bc000) vaddr(0x3fd4bf6000) stride(2560) length(3686400)
Jan  1 00:00:43 licheervnano-7dc2 local5.warn : [LOG-WRN] sensor_test.c:153:_vi_get_chn_frame(): plane(1): paddr(0x8dc40000) vaddr(0x3fd4f7a000) stride(2560) length(1843200)
Jan  1 00:00:43 licheervnano-7dc2 local5.warn : [LOG-WRN] sensor_test.c:246:sensor_dump_yuv(): ms consumed: 789.479004
Jan  1 00:00:43 licheervnano-7dc2 local5.warn : [LOG-WRN] sensor_test.c:254:sensor_dump_yuv(): VI GetChnFrame OK(2) NG(0)
Jan  1 00:00:43 licheervnano-7dc2 local5.warn : [LOG-WRN] sensor_test.c:256:sensor_dump_yuv(): Dump VI yuv TEST-PASS

以及我分不清楚是uv反了还是红蓝反了:(

屏幕截图_20240524_112938

这是手机拍的现场图片

lxowalle commented 5 months ago

看了下新版的确实有问题,可以先回退版本,commit 646bd604472e73f41b418483d5218223ebcf021e (HEAD, tag: 20240514)

981213 commented 5 months ago

回退版本后颜色恢复正常。感谢回复!

Z2Z-GuGu commented 5 months ago

问题已修复,请更新至最新分支,详见https://github.com/sipeed/LicheeRV-Nano-Build/commit/58f1952f918ce20e890db96cce5b0f22a7194daa

981213 commented 5 months ago

@Z2Z-GuGu

对比原本引入这个改动的代码:

https://github.com/sipeed/LicheeRV-Nano-Build/commit/20a606bbdbd5a03d7c3064dd8b71285633f35a94#diff-0c143fcccecb2d9bbe53b84bce1a1a32506e6439532797576a64d8e4d47f3abf

enBayerFormat在改动前是BAYER_FORMAT_GR而不是BAYER_FORMAT_RG(实话说我没研究过这是啥所以也不知道哪个是对的)

以及 这个修法 看着有点给后人挖坑的样子… 就是我不知道这个坑是 https://github.com/sipeed/LicheeRV-Nano-Build/commit/20a606bbdbd5a03d7c3064dd8b71285633f35a94 埋下的还是早在提交代码之前的修改导致的。

上面那个引入错误改动的diff一次性修改了所有同一case下的传感器数据参数。在未核实整个case下所有传感器参数时,针对单一传感器参数错误的修正方式应该是把它从这一case中去掉并新增一段case/赋值/break。比较优雅一点的做法应该是针对https://github.com/sipeed/LicheeRV-Nano-Build/commit/20a606bbdbd5a03d7c3064dd8b71285633f35a94 中增加的传感器(如果是这条提交引入的错误)或者针对GC4653(如果是在这之前引入的错误)单独新增case,而不是一次改变列表中多个无关/未测试传感器的参数。

Z2Z-GuGu commented 5 months ago

感谢指正,BAYER_FORMAT_GR和BAYER_FORMAT_RG经测试是一样的,在这里没分的那么清。这个问题是之前适配OA04A10时候留下的坑,算能提供的OA04A10颜色矫正文件中红蓝反了,当时为了方便测试,直接改了这里的enBayerFormat,后来忘记改回来了。这次修改把GC4653和上面的格式修正了,下次提交我会针对OA04A10单独开一条case。

981213 commented 5 months ago

测试可用,感谢修复!