天天看點

第九章:mmp功能子產品1、簡介2、什麼是視訊緩沖池3、相關的資料結構和API4、vpss基礎知識5、VI/VPSS 離/線上模式

1、簡介

    海思提供的媒體處理軟體平台(Media Process Platform,簡稱 MPP)                         

第九章:mmp功能子產品1、簡介2、什麼是視訊緩沖池3、相關的資料結構和API4、vpss基礎知識5、VI/VPSS 離/線上模式

VDEC用來解碼的,比如磁盤裡面有一個

VDA對視訊内容簡單的偵測

VPSS處理

VO是用于直接顯示的。

2、什麼是視訊緩沖池

(1)視訊的本質是多幀圖檔,圖檔的本質是RGB或rawRGB資料,要占用一段連續記憶體

(2)視訊的裁剪、縮放、修正處理等各種操作,本質上就是對記憶體中的資料進行運算

(3)視訊緩存池(VB, video buffer)就是一段很大,又被合理劃分和管理的記憶體,用來做視訊資料的暫存和運算場地

(4)公共視訊緩存池的公共2字,可以了解為全局變量,也就是各個子產品都能通路的一段記憶體

(5)看似視訊緩存塊在各個子產品之間流轉,實際上并沒有記憶體複制,而是指針在傳遞

(6)視訊緩存池的記憶體由MPP來維護,我們在系統啟動時就把整個SDRAM分成了2部分:系統部分(由linux kernel來維護管理)和mpp部分(由mpp系統來維護管理)

(7)緩存池需要幾個,每個中包含幾個緩存塊,每個緩存塊多大,都是可以由使用者程式設定好參數,然後調用MPP的相應API來向MPP申請配置設定的。

第九章:mmp功能子產品1、簡介2、什麼是視訊緩沖池3、相關的資料結構和API4、vpss基礎知識5、VI/VPSS 離/線上模式

       海思3518e裡面有多個緩沖池,一個緩沖池裡面又有很多緩沖塊,大小相同位址相連,緩沖池的數量由記憶體大小決定(應該是自行劃定的吧,還未求證)這些都是由mpp維護的。

       視訊處理流程大緻如下,先從緩沖池取出一個緩沖塊,然後放入VI中,将一幀資料填充進bm,之後傳入vpss進行處理,然後将處理完是資料放入新的緩沖塊中,最後将剛剛使用過的Bmijk緩沖塊釋放回去。

3、相關的資料結構和API

(1)VB_CONF_S:用于參數設定的,設定緩沖池有幾個,緩沖塊的數量大小等。

typedef struct hiVB_CONF_S
{
    HI_U32 u32MaxPoolCnt;   //設定申請最多緩沖池的數量,範圍是0- 16/* max count of pools, (0,VB_MAX_POOLS]  */    
    struct hiVB_CPOOL_S
    {
        HI_U32 u32BlkSize;		//緩沖塊大小
        HI_U32 u32BlkCnt;		//緩沖塊數量
        HI_CHAR acMmzName[MAX_MMZ_NAME_LEN];	//緩沖池的名字,用于調試階段可以看到名字
    }astCommPool[VB_MAX_COMM_POOLS];//最大上限16個公共緩沖池
} VB_CONF_S;
           

(2)HI_MPI_VB_SetConf:API,用于将緩沖池資訊設定到mpp系統中

(3)HI_MPI_VB_Init     :API,執行設定緩沖池的操作。

【舉例】

HI_S32 s32ret;
VB_CONF_S stVbConf;
memset(&stVbConf,0,sizeof(VB_CONF_S));
stVbConf.u32MaxPoolCnt = 128;	//設定緩沖池數量最大上限
stVbConf.astCommPool[0].u32BlkSize = 768*576*2;	//設定第一個緩沖塊大小
stVbConf.astCommPool[0].u32BlkCnt = 20;			//設定第一個緩沖塊數量
stVbConf.astCommPool[1].u32BlkSize = 384*288*2;	//設定第二個緩沖塊大小
stVbConf.astCommPool[1].u32BlkCnt = 40;			//設定第二個緩沖塊數量
s32ret = HI_MPI_VB_SetConf(&stVbConf);			//将緩沖池資訊設定到mpp系統中
if (HI_SUCCESS != s32ret)	
{
printf("set vb err:0x%x\n", s32ret);
return s32ret;
}
s32ret = HI_MPI_VB_Init();						//初始化
if (HI_SUCCESS != s32ret)
{
printf("init vb err:0x%x\n", s32ret);
return s32ret;
} 
           

       SAMPLE_VENC_1080P_CLASSIC();函數主要工作流程。

       程式主要是為了錄像,指揮攝像頭采集圖像,然後将圖像編碼最後輸出碼流。

       第一部分:初始化sys部分的變量,sys也就是mpp中的變量填充,列如VB結構體裡面的資料

       第二部分:初始化mpp系統

       第三部分:啟動VI部分(裝置和通道),然後采集圖像(和攝像頭相關部分)

       第四部分:啟動VPSS,然後将vi處理完的資料傳給vpss(使用bind函數将vi和vpss綁定在一起)

       第五部分:啟動編碼,這部分由mpp内部完成,僅調用相關API即可。

       第六部分:僅僅隻是将流資料儲存成檔案。

3.1、第一部分詳解

       首先清空VB_CONF_S結構體,為了後續填充變量做準備。

       然後調用SAMPLE_COMM_VI_GetSizeBySensor(PIC_SIZE_E *penSize)這個函數,傳入enSize數組,在這個函數裡面可以看到

       SAMPLE_VI_MODE_E enMode = SENSOR_TYPE;,其中SENSOR_TYPE是在外部makefile中定義的,通過SENSOR_TYPE來确定enSize的内容,enSize是用于存放将來編碼之後傳輸出來的碼流。

        s32ChnNum是設定輸出多少個碼流。

       其中碼流輸出的圖像是一緻的,但是分辨率大小是不一樣的,其中一路是主碼流,其他的則是從主碼流中裁剪縮放而來的。

       一個緩沖池對應一個碼流。

SAMPLE_COMM_SYS_CalcPicVbBlkSize(VIDEO_NORM_E enNorm, PIC_SIZE_E enPicSize, PIXEL_FORMAT_E enPixFmt, HI_U32 u32AlignWidth)
這個函數是用于計算出一個緩沖塊需要多大空間。
VIDEO_NORM_E enNorm:傳入視訊格式,PAL制和NTSC制 
PIC_SIZE_E enPicSize:圖像尺寸
PIXEL_FORMAT_E enPixFmt:像素格式
HI_U32 u32AlignWidth:需要對齊排布的大小
其中這個函數的塊大小=圖像大小(根據長寬高和像素格式求得)+頭資訊。
           
u32VbSize = (CEILING_2_POWER(stSize.u32Width, u32AlignWidth) * \
            CEILING_2_POWER(stSize.u32Height,u32AlignWidth) * \
           ((PIXEL_FORMAT_YUV_SEMIPLANAR_422 == enPixFmt)?2:1.5));
#define CEILING_2_POWER(x,a)     ( ((x) + ((a) - 1) ) & ( ~((a) - 1) ) )//x往a上除,直到能被整除
           

第二部分

       SAMPLE_COMM_SYS_Init(&stVbConf);

第三部分詳解

       學習方法:繪制調用關系圖譜

       (1)簡單浏覽VI部分的調用層次,發現很複雜

       (2)有些函數是sample寫的,有些是調用MPP的,資料結構也是2種都有

       SAMPLE_xxx就是sample内部自己實作的

       HI_MPI_xxx就是調用mmp

       (3)學習重點1:全局把控熟悉整個過程全景視圖。

       (4)學習重點2:掌握細節資料結構元素含義,和遇到的概念。

       (5)學習重點3:知道某些關鍵操作在哪裡定義,哪裡設定,将來需要改的時候能找到地方 。

main
	SAMPLE_VENC_1080P_CLASSIC
		SAMPLE_COMM_VI_GetSizeBySensor(step1)
		SAMPLE_COMM_SYS_CalcPicVbBlkSize	
			SAMPLE_COMM_SYS_GetPicSize
		SAMPLE_COMM_SYS_Init(step2)
			HI_MPI_SYS_Exit();	
			HI_MPI_VB_Exit();
			HI_MPI_VB_SetConf
			HI_MPI_VB_Init
			HI_MPI_SYS_SetConf
			HI_MPI_SYS_Init
		SAMPLE_COMM_VI_StartVi(step3)----------------------->
    stViConfig.enViMode   = SENSOR_TYPE;	//sensor的類型
    stViConfig.enRotate   = ROTATE_NONE;	//輸出圖像是否旋轉(0、90、180°等)
    stViConfig.enNorm     = VIDEO_ENCODING_MODE_AUTO;//圖像制式(PAL、NTSC)
    stViConfig.enViChnSet = VI_CHN_SET_NORMAL;		//圖像加工(鏡像、翻轉等)
    stViConfig.enWDRMode  = WDR_MODE_NONE;		//WDR寬動态
			IsSensorInput
			SAMPLE_COMM_VI_StartIspAndVi
				SAMPLE_COMM_VI_StartMIPI(1)//對sensor做必要的初始化
//mipi是sensor和主晶片hi3518e之間的一種接口
//常用的接口有MIPI、LVDS、DC
					SAMPLE_COMM_VI_SetMipiAttr
						fd = open("/dev/hi_mipi", O_RDWR);
						ioctl(fd, HI_MIPI_SET_DEV_ATTR, pstcomboDevAttr)
				SAMPLE_COMM_ISP_Init(2)//isp就是image signal process,圖像信号處理
                   //HI3518E内部的ISP硬體單元是隸屬于VI子產品的
					sensor_register_callback		//在sensor驅動中,在/component/isp/sensor
					HI_MPI_AE_Register		//注冊3A單元:自動曝光
					HI_MPI_AWB_Register		//注冊3A調試:自動白平衡
					HI_MPI_AF_Register		//注冊3A調試:自動對焦
					HI_MPI_ISP_MemInit		//配置設定記憶體單元
					HI_MPI_ISP_SetWDRMode	//寬動态
					HI_MPI_ISP_SetPubAttr		--------------------->
   根據sensor的類型進行設定,填充stPubAttr結構體。
   以AR0130為例
    stPubAttr.enBayer               = BAYER_GRBG;	//參考sensor手冊得知,像素排列順序
    stPubAttr.f32FrameRate          = 30;		//幀率
    stPubAttr.stWndRect.s32X        = 0;		//圖像區域的起始點X
    stPubAttr.stWndRect.s32Y        = 0;		//圖像區域的起始點Y
    stPubAttr.stWndRect.u32Width    = 1280;	//圖像長
    stPubAttr.stWndRect.u32Height   = 720;	//圖像寬
					HI_MPI_ISP_Init	//初始化isp子產品
				SAMPLE_COMM_ISP_Run(3)//建立線程運作isp
					pthread_create(&gs_IspPid, &attr, (void* (*)(void*))Test_ISP_Run, NULL)
						Test_ISP_Run
							HI_MPI_ISP_Run
				SAMPLE_COMM_VI_StartDev(4)
					HI_MPI_VI_SetDevAttr		//在step3中設定的參數,一路傳到這才被寫入硬體單元
					HI_MPI_ISP_GetWDRMode	//在上一步isp中設定了SetWDRMode,這一步擷取設定資訊
					HI_MPI_VI_SetWDRAttr
					HI_MPI_VI_EnableDev		//啟動硬體單元
				SAMPLE_COMM_VI_StartChn(5)	//設定主通道
					HI_MPI_VI_SetChnAttr		//
					HI_MPI_VI_SetRotate
					HI_MPI_VI_EnableChn					
		SAMPLE_COMM_SYS_GetPicSize(step4)//得到處理圖像的長和高
		SAMPLE_COMM_VPSS_StartGroup		//開啟Group
   HI_MPI_VPSS_CreateGrp	//先建立一個Group
   HI_MPI_VPSS_GetNRParam//擷取NR的參數(降噪相關的)
   HI_MPI_VPSS_SetNRParam//在寫入進去(如果要做降噪相關的處理就需要在這之前對參數進行修改)
   HI_MPI_VPSS_StartGrp	//最後再啟動
		SAMPLE_COMM_VI_BindVpss	//将Vpss建立出來的Group和Vi的channel綁定在一起。
   HI_MPI_SYS_Bind	//調用海思驅動。
		SAMPLE_COMM_VPSS_EnableChn------------------------->
 	    VpssChn = 0;		//通道号
	    stVpssChnMode.enChnMode      = VPSS_CHN_MODE_USER;	//設定通道模式為使用者模式
	    stVpssChnMode.bDouble        = HI_FALSE;				//現場幀率模式傳輸(不了解)
	    stVpssChnMode.enPixelFormat  = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
	    stVpssChnMode.u32Width       = stSize.u32Width;			//該通道輸出圖像的長
	    stVpssChnMode.u32Height      = stSize.u32Height;			//該通道輸出圖像的寬
	    stVpssChnMode.enCompressMode = COMPRESS_MODE_SEG;//内部壓縮圖像的模式
		SAMPLE_COMM_VENC_Start(step5)//
		SAMPLE_COMM_VENC_BindVpss//綁定Vpss和Venc的channel綁定在一起。
		SAMPLE_COMM_VENC_StartGetStream(step6)//
   SAMPLE_COMM_VENC_GetVencStreamProc
   	    HI_MPI_VENC_GetChnAttr
     SAMPLE_COMM_VENC_GetFilePostfix
     HI_MPI_VENC_GetFd
     HI_MPI_VENC_Query	//傳回狀态資訊
     HI_MPI_VENC_GetStream
     SAMPLE_COMM_VENC_SaveStream//儲存流檔案
SAMPLE_COMM_VENC_SaveH264
     HI_MPI_VENC_ReleaseStream	//
		SAMPLE_COMM_VENC_StopGetStream(step7)
           

4、vpss基礎知識

       全稱:Video Process Sub-System

       支援對一幅輸入圖像進行統一預處理,如去噪、去隔行等,然後再對各通道分别進行縮放、銳化等處理,最後輸出多種不同分辨率的圖像。

概念:

       GROUP:VPSS 對使用者提供組(GROUP)的概念,各 GROUP 分時複用 VPSS 硬體。每個 VPSS GROUP 包含多個通道,通道數目視方案實作有所不同。

       CHANNEL:VPSS 組的通道。通道分為 2 種:實體通道和擴充通道。VPSS 硬體提供多個實體通道,每個通道具有縮放、裁剪等功能。擴充通道具備縮放功能,它通過綁定實體通道,将實體通道輸出作為自己的輸入,把圖像縮放成使用者設定的目标分辨率輸出。擴充通道借助實體通道的輸出來進行處理。

       FRC:幀率控制,分為 2 種:group 幀率控制和 chn 幀率控制。例如可變幀率的錄制。

       Crop:裁剪,分為 3 種:group 的裁剪和實體通道的裁剪以及擴充通道的裁剪。

       −  Group 的裁剪,VPSS 對輸入圖像進行裁剪。

       −  實體通道的裁剪,VPSS 對各個實體通道的輸出圖像進行裁剪。

       −  擴充通道的裁剪,VPSS 調用 VGS 對擴充通道的輸出圖像進行裁剪。

       DEI:De-interlace,去隔行。将交錯的隔行視訊源還原成逐行視訊源。

       NR:去噪。通過參數配置,把圖像中的高斯噪聲去除,使得圖像變得平滑,有助于降低編碼碼率。

       Scale:縮放,對圖像進行縮小放大。

       LDC:Lens Distortion Correction,鏡頭畸變校正,一些低端鏡頭容易産生圖像畸變,需要根據畸變程度對其圖像進行校正。

       Cover:視訊遮擋區域,對 VPSS 的輸出圖像填充純色塊。

      Overlay:視訊疊加區域,在 GROUP 上進行位圖的加載和背景色更新,支援 ARGB4444、ARGB1555、ARGB8888 三種格式的位圖。

       Border:邊框,VPSS 在輸出圖像上加邊框。

       備份節點:原始圖像的備份節點。每個 GROUP 都有一個備份節點,用于備份即将送出硬體處理的那幀原始圖像。VPSS 在以下情況會将緩存隊列隊頭節點的圖像放入備份節點:

       −  當隊頭節點的圖像要經過 VPSS 硬體處理時,VPSS 會将其放入備份節點,并替換掉原有圖像。

       −  當後端綁定的接收子產品要求 VPSS 将隊頭圖像放入備份節點時,VPSS 也會替換備份節點中的圖像,即使該圖像不經過硬體處理。

       低延時:在 VI—VPSS 的線上方案中,編碼器性能足夠的情況下,VPSS 支援按照,以行為機關,邊采集邊發送的方式,将圖像發送給編碼子產品進行編碼,用來減少 VPSS處理完整幀圖像再發送給編碼子產品過程中,資料的延時時間。這樣的方式即為低延時方案。

5、VI/VPSS 離/線上模式

       VI/VPSS 離線模式是指 VI 進行時序解析後将圖像資料寫出到 DDR,VPSS 從DDR 中載入 VI 采集的資料進行圖像處理,是傳統Hi3518/Hi3520D 等晶片的VI/VPSS 的協作模式。

       VI/VPSS 線上模式是指 VI 進行時序解析後直接在晶片内部将資料傳遞到 VPSS,中間無 DDR 寫出的過程(少了一次到兩次的記憶體複制)。線上模式可以省一定的帶寬和記憶體,降低端到端的延時。需要注意的是,線上模式時,因為 VI 不寫出資料到 DDR,無法進行CoverEx、OverlayEx、Rotate、LDC 等操作,需要在 VPSS 各通道寫出後再進行Rotate/LDC 等處理,而且有些功能隻在離線下能支援,比如 DIS。

第九章:mmp功能子產品1、簡介2、什麼是視訊緩沖池3、相關的資料結構和API4、vpss基礎知識5、VI/VPSS 離/線上模式

       通過調用HI_MPI_SYS_Bind函數可以将可與 VI 和 VO/VENC/IVE 等子產品進行綁定,其中前者為 VPSS 的輸入源(VO),後者為 VPSS 的接收者。每個 GROUP 僅可與一個輸入源綁定。GROUP 的實體通道有兩種工作模式:AUTO 和 USER,兩種模式間可動态切換。預設的工作模式為 AUTO,此模式下各通道僅可與一個接收者綁定。USER 模式主要用于對同一通道圖像進行多路編碼的場景。

       注:Hi3516A/Hi3518EV200/Hi3519V100 僅支援 USER 工作模式。

       VENC 子產品,即視訊編碼子產品。本子產品支援多路實時編碼,且每路編碼獨立,編碼協定和編碼 profile(圖像不同的清晰度标準) 可以不同。本子產品支援視訊編碼同時,排程 Region 子產品對編碼圖像内容進行疊加(OSD)和遮擋。

第九章:mmp功能子產品1、簡介2、什麼是視訊緩沖池3、相關的資料結構和API4、vpss基礎知識5、VI/VPSS 離/線上模式

       BP:基本的,清晰度不怎麼樣,但編碼速度快。

       MP:主流的,性能平衡。

       HP:高清的,清晰度最好的。

第九章:mmp功能子產品1、簡介2、什麼是視訊緩沖池3、相關的資料結構和API4、vpss基礎知識5、VI/VPSS 離/線上模式

       視訊編碼的流程:典型的編碼流程包括了輸入圖像的接收、圖像内容的遮擋和覆寫、圖像的編碼、以及碼流的輸出等過程。

第九章:mmp功能子產品1、簡介2、什麼是視訊緩沖池3、相關的資料結構和API4、vpss基礎知識5、VI/VPSS 離/線上模式

       碼率控制器:碼率控制器實作對編碼碼率進行控制。

       從資訊學的角度分析,圖像的壓縮比越低,壓縮圖像的品質越高;圖像壓縮比例越高,壓縮圖像的品質越低。對于場景變化的真實場景,圖像品質穩定,編碼碼率會波動;編碼碼率穩定,圖像品質會波動(例如運動視訊,如果壓縮度過高,就會破壞視訊品質)。以 H.264 編碼為例,通常圖像 Qp 越低,圖像的品質越好,碼率越高;圖像 Qp (h.264編碼中的一個概念)越高,圖像品質越差,碼率越低。

       碼率控制器分别提供了對 H.264\H.265\MJPEG 協定編碼通道 CBR、VBR、FIXQP 等三種碼率控制模式,對圖像品質和碼率進行調節。

       CBR(Constant Bit Rate)固定比特率。即在碼率統計時間内保證編碼碼率平穩。碼率穩定主要由兩個量來評估,這兩個量都可以由使用者在建立編碼通道時指定。

       VBR(Variable Bit Rate)可變比特率,即允許在碼率統計時間内編碼碼率波動,進而保證編碼圖像品質平穩。以 H.264 編碼為例,VENC 子產品提供使用者可設定 MaxQp,MinQp,MaxBitrate 和 ChangePos。MaxQp,MinQp 用于控制圖像的品質範圍,MaxBitrate 用于鉗位碼率統計時間内的最大編碼碼率,ChangePos 用于控制開始調整Qp 的碼率基準線。

       Fix Qp 固定 Qp 值。在碼率統計時間内,編碼圖像所有宏塊 Qp 值相同,采用使用者設定的圖像 Qp 值,I 幀和 P 幀的 QP 值可以分别設的置。

繼續閱讀