基於Hi3559AV100 RFCN實現細節解析-(3)系統輸入VI分析(HiISP)二 :

  下面隨筆系列將對Hi3559AV100 RFCN實現細節進行解析,整個過程涉及到VI、VDEC、VPSS、VGS、VO、NNIE,其中涉及的內容,大家可以參考之前我寫的部落格:

基於Hi3559AV100 RFCN實現細節解析-(3)系統輸入VI分析一 : 

//www.cnblogs.com/iFrank/p/14481080.html

  整個的RFCN VI實現過程在上一篇隨筆已經介紹了,函數具體含義也通過注釋進行了一一的說明,而在VI初始化過程中,用到了ISP(Image Signal Processing) 影像訊號處理的相關知識,海思也為其定義了API介面,下面隨筆將介紹ISP相關概念,具體參考《HiISP開發參考》,方便大家對VI整個過程進行了更為清晰的認識。

1、基本概述

  ISP 通過一系列數字影像處理演算法完成對數字影像的效果處理。主要包括 3A、壞點校正、去噪、強光抑制、背光補償、色彩增強、鏡頭陰影校正等處理。ISP 包括邏輯部分以及運行在其上的 firmware。

1.1、功能描述

  ISP 的控制結構如圖 1所示,lens 將光訊號投射到 sensor 的感光區域後,sensor 經過光電轉換,將 Bayer 格式的原始影像送給 ISP,ISP 經過演算法處理,輸出 RGB 空間域的影像給後端的影片採集單元。在這個過程中,ISP 通過運行在其上的 firmware 對 ISP邏輯,lens 和 sensor 進行相應控制,進而完成自動光圈、自動曝光、自動白平衡等功能。其中,firmware 的運轉靠影片採集單元的中斷驅動。PQ Tools 工具通過網口或者串口完成對 ISP 的在線影像品質調節。
圖1 ISP控制結構示意圖
 
  ISP 由 ISP 邏輯及運行在其上的 Firmware 組成,邏輯單元除了完成一部分演算法處理外,還可以統計出當前影像的實時資訊。Firmware 通過獲取 ISP 邏輯的影像統計資訊,重新計算,回饋控制 lens、sensor 和 ISP 邏輯,以達到自動調節影像品質的目的。

1.2、ISP構架

  ISP 的 Firmware 包含三部分,一部分是 ISP 控制單元和基礎演算法庫,一部分是AE/AWB 演算法庫,一部分是 sensor 庫。Firmware 設計的基本思想是單獨提供 3A 演算法庫,由 ISP 控制單元調度基礎演算法庫和 3A 演算法庫,同時 sensor 庫分別向 ISP 基礎演算法庫和 3A 演算法庫註冊函數回調,以實現差異化的 sensor 適配。ISP firmware 架構如圖 2 所示。 

 圖2 ISP firmware構架

  不同的 sensor 都以回調函數的形式,向 ISP 演算法庫註冊控制函數。ISP 控制單元調度基礎演算法庫和 3A 演算法庫時,將通過這些回調函數獲取初始化參數,並控制 sensor,如調節曝光時間、模擬增益、數字增益,控制 lens 步進聚焦或旋轉光圈等。

1.3、Firmware內部流程

  Firmware 內部流程分兩部分,一部分是初始化任務,主要完成 ISP 控制單元的初始化、ISP 基礎演算法庫的初始化、3A 演算法庫的初始化,包括調用 sensor 的回調獲取 sensor 差異化的初始化參數;另一部分是動態調節過程,在這個過程中, firmware 中的 ISP 控制單元調度 ISP 基礎演算法庫和 3A 演算法庫,實時計算並進行相應控制。Firmware 的軟體結構如圖

3 所示。 
 

圖3 ISP firmware 軟體結構

2、軟體流程

  ISP 作為前端採集部分,需要和影片採集單元(VIU)協同工作。ISP 初始化和基本配置完成後,需要 VIU 進行介面時序匹配。一是為了匹配不同 sensor 的輸入時序,二是為 ISP 配置正確的輸入時序。待時序配置完成後,ISP 就可以啟動 Run 來進行動態影像品質調節。此時輸出的影像被 VIU 採集,進而送去顯示或編碼。軟體使用流程如圖4所示。 
 
 

圖4 ISP firmware 使用流程

  PQ Tools 工具主要完成在 PC 端進行動態影像品質調節,可以調節多個影響影像品質的因子,如去噪強度、色彩轉換矩陣、飽和度等。 

  如果用戶調試好影像效果後,可以使用 PQ Tools 工具提供的配置文件保存功能進行配
置參數保存。在下次啟動時系統可以使用 PQ Tools 工具提供的配置文件載入功能載入
已經調節好的影像參數。 
 

下面給出程式碼示例:

 1 HI_S32 s32Ret;
 2 ALG_LIB_S stAeLib;
 3 ALG_LIB_S stAwbLib;
 4 ISP_PUB_ATTR_S stPubAttr;
 5 pthread_t isp_pid;
 6 VI_PIPE ViPipe = 0;
 7 
 8 /* 註冊sensor庫 */
 9 s32Ret = sensor_register_callback(ViPipe, &stAeLib, &stAwbLib);
10 if (HI_SUCCESS != s32Ret) {
11     printf(」register sensor failed!\n」);
12     return s32Ret;
13     }
14 /* 註冊海思AE演算法庫 */
15 stAeLib.s32Id = 0;
16 strcpy(stAeLib.acLibName, HI_AE_LIB_NAME);
17 s32Ret = HI_MPI_AE_Register(ViPipe, &stAeLib);
18 
19 if (HI_SUCCESS != s32Ret) {
20     printf(」register ae lib failed!\n」);
21     return s32Ret;
22 }
23 /* 註冊海思AWB演算法庫 */
24 stAwbLib.s32Id = 0;
25 strcpy(stAwbLib.acLibName, HI_AWB_LIB_NAME);
26 
27 s32Ret = HI_MPI_AWB_Register(ViPipe, &stAwbLib);
28 if (HI_SUCCESS != s32Ret) {
29     printf(」register awb lib failed!\n」);
30     return s32Ret;
31 }
32  /* 初始化ISP外部暫存器 */
33  s32Ret = HI_MPI_ISP_MemInit(ViPipe);
34  if (s32Ret != HI_SUCCESS)
35  {
36     printf("%s: HI_MPI_ISP_Init failed!\n", __FUNCTION__);
37     return s32Ret;
38  }
39 
40 /* 配置影像公共屬性 */
41  s32Ret = HI_MPI_ISP_SetPubAttr(ViPipe, &stPubAttr);
42 if (s32Ret != HI_SUCCESS)
43 {
44     printf("%s: HI_MPI_ISP_SetPubAttr failed with %#x!\n", __FUNCTION__, 
45     s32Ret);
46     return s32Ret;
47 }
48 /* 初始化ISP Firmware */
49 s32Ret = HI_MPI_ISP_Init(ViPipe);
50 if (HI_SUCCESS != s32Ret) {
51     printf(」isp init failed!\n」);
52     return s32Ret;
53 }
54 
55 /* HI_MPI_ISP_Run單獨啟動執行緒運行 */
56 if (0 != pthread_create(&isp_pid, 0, ISP_Run, NULL)){
57     printf("create isp running thread failed!\n");
58     return HI_FAILURE;
59 }
60 /* 啟動VI/VO等業務 */
61 //……
62 
63 /* 停止VI/VO等業務 */
64 s32Ret = HI_MPI_ISP_Exit(ViPipe);
65 if (HI_SUCCESS != s32Ret) {
66     printf(」isp exit failed!\n」);
67     return s32Ret;
68 }
69 
70 pthread_join(isp_pid, 0);
71 return HI_SUCCESS;