1. 程式人生 > >視訊處理之OSD

視訊處理之OSD

[欲觀原文,請君移步](https://mp.weixin.qq.com/s?__biz=MzI4NjE3MzUwMA==&mid=2652138782&idx=1&sn=f237212c50852fb3b3c678f805f6ec5f&chksm=f0003d4dc777b45b90e22a4cf78b0eee29e794acf8637e4547c274e16a51bcd41c21e70781fa&token=1491409841&lang=zh_CN#rd) #OSD簡介 OSD,on-screen display的簡稱,即螢幕選單式調節方式。一般我們按一下Menu鍵後螢幕彈出的顯示器各項調節專案資訊的矩形選單,比如調亮度,色調,飽和度等資訊,這個顯示這個選單的功能就是視訊行業的OSD。 #基於FPGA的OSD設計與實現 ##1 Xilinx OSD IP功能 - 支援最多8個layer - 背景顏色可程式設計 - 位置,大小,顏色,透明度(alpha)可程式設計 - 支援RGB和YUV視訊流 ##2 硬體結構框圖 硬體平臺是基於xilinx xc7z035晶片開發的,關鍵模組框圖如下圖1所示。 - **一個時序產生模組Video Timing Controller(在本次實驗中採用1080P標準時序)** - **首先PL端將視訊流通過VDMA讀出,輸出介面為AXI4-Stream的資料流** - **然後視訊流進入OSD IP(OSD輸入輸出也是AXI4-Stream介面)** - **最後OSD輸出資料流與1080P時序同時送入到AXI4-Stream to Video Out模組,輸出為HDMI介面** ![圖1](https://imgkr.cn-bj.ufileos.com/de885606-e1fb-4986-8f7d-dee54aedf035.png) 下面小編會詳細介紹OSD IP的例化與使用 ##3 OSD PL端 >如果在使用OSD IP過程中出現如下錯誤,請在xilinx官網上申請OSD的License,這裡不再詳述如何申請License。 ![](https://imgkr.cn-bj.ufileos.com/bf4b4b65-109b-4498-9a33-8b5959f86387.png) 首先在Block Design中加入Video On Screen Display,開啟後會看到如下圖2。 **(1) 勾選AXI-Lite Interface:PS端通過AXI-Lite進行配置該IP** **(2) Video Format選擇RGB** **(3) Layers選擇2** **(4) Layer Configuration:LAYER0選擇外部視訊流,也就是實時視訊,LAYER1選擇Internal,PS端可以控制進行圖文疊加** ![圖2](https://imgkr.cn-bj.ufileos.com/f9d3a217-1354-4221-97d8-2eaf91f8b32a.png) 點選Screen Layout Options,如圖3所示 **(1) Background size(選擇背景大小)裡寬度輸入1920,高度輸入1080** **(2) Background color輸入背景顏色,這裡選擇黑色,可以通過axi-lite來控制** **(3) layer0因為選擇的是外部視訊流,所以比如設定為外部視訊流解析度,輸錯了,可能無法正常使用,小編已經遇到過了,本文使用1920x1080外部視訊流** **(4) layer1因為選擇的是內部影象控制器,所以無所謂設定什麼,可以通過axi-lite控制,所以選擇預設即可** ![圖3](https://imgkr.cn-bj.ufileos.com/4c8ec7b6-2e7f-459d-b467-5bf56e2a6cdd.png) 點選LAYER 1 Options出現圖4介面:因為是內部影象控制器,所以可以進行一些配置,比如顏色多少,字元數目,位元畫素等等,這裡小編選擇的是預設。 ![圖4](https://imgkr.cn-bj.ufileos.com/d2f53abb-d2b3-4cb8-a60f-d367bf875ec2.png) 配置完OSD IP後,將其AXI-lite掛在總線上即可,然後儲存Block Design即可。 **注:點開Address Editor,一定要確定該IP被分配地址空間,如果沒有,點選一下自動分配(小編遇到的問題就是這個ip地址空間在unmap裡,導致後續PS端OSD IP無法初始化)。** ![圖4](https://imgkr.cn-bj.ufileos.com/091542b1-a50e-42bb-97a0-b4bf1b38f17a.png) ##4 OSD PS端 下面就是常規操作include bitstream匯出SDK,其實就是生成hdf檔案,硬體資訊。然後就launch SDk。如圖4所示,可以看到hdf檔案裡都有什麼。 ![圖4](https://imgkr.cn-bj.ufileos.com/77482212-e31d-4a7d-a953-a9851d220db9.png) 新建一個design_top的空工程,如圖5所示,在design_top_bsp下面可以看到system.mss檔案,在紅框中找到OSD IP。 ![圖5](https://imgkr.cn-bj.ufileos.com/6a442844-6c16-49ce-a1db-60fca55079d9.png) 點選import examples,出現如圖6所示,勾選對話方塊後選擇OK(不會玩IP先整個example)。 ![圖6](https://imgkr.cn-bj.ufileos.com/d059645f-f772-48b2-a541-6444a8487342.png) 開啟XosdSelfTestExample.c即可看到該例子程式是怎麼個處理流程(圖7為main函式,圖8為使用流程)小編稱之為PS端IP使用三步法 - 第一步先進行lookup該IP - 第二步就是初始化該IP - 第三步就是使用IP ![圖7](https://imgkr.cn-bj.ufileos.com/bb8936c7-f5de-4ebe-a74a-650bff2c7b6c.png) ![圖8](https://imgkr.cn-bj.ufileos.com/e00569f1-516c-45f1-ad1f-ae2afea20614.png) 執行一下,結果如圖9所示,可以看到UART會列印OSD成功資訊。 ![圖9](https://imgkr.cn-bj.ufileos.com/fae5c527-71b8-443c-9fba-73d05af379d8.png) #OSD 例項 閒話不說,上面經過了OSD example,小編也作為一個PS端初學者來玩一玩。 >尷尬的是經常在寫c程式碼的時候想著寫begin...end,真是verilog寫習慣了,思想難以改變,原來是花括弧啊{} ##初始化模組如下 在初始化後必須將該模組進行復位,然後,否則該IP啟動不了。 ```c int OsdInit(int DeviceID) { int Status; /* Initialize the OSD instance */ OsdCfgPtr = XOSD_LookupConfig(DeviceID); Status = XOSD_CfgInitialize(&Osd, OsdCfgPtr,OsdCfgPtr->BaseAddress); if (Status != XST_SUCCESS) return 1; /* Reset the devices */ XOSD_Reset(&Osd); /* Enable the OSD device and tell it to pick up the register changes */ XOSD_Enable(&Osd); XOSD_RegUpdateEnable(&Osd); return 0; } ``` ##配置模組 這裡需要注意的是把BANKIndex輸入為1,否則會進行字元填寫方式就需要改變,不符合操作習慣XOSD_LoadCharacterSetBank(&Osd, Gcindex, 1, (u32 *)Font); ```c void Graphics_setting(u8 Gcindex,u8 LayerPriority,u32 ColorData[],u32 *TextData) { int width = 1920; int height = 1080; int LayerAlphaValue = 0xFF; int LayerGlobalAlphaEnable = 0; XOSD_SetLayerAlpha(&Osd, Gcindex, LayerGlobalAlphaEnable,LayerAlphaValue); XOSD_SetLayerPriority(&Osd, Gcindex, LayerPriority); XOSD_SetLayerDimension(&Osd, Gcindex, 0, 0, width, height); XOSD_EnableLayer(&Osd, Gcindex); /* Load color, font and text and set the active banks */ XOSD_LoadColorLUTBank(&Osd, Gcindex, 0, ColorData); //set BankIndex is 1(fit our keyboard) XOSD_LoadCharacterSetBank(&Osd, Gcindex, 1, (u32 *)Font); XOSD_LoadTextBank(&Osd, Gcindex, 0, (u32 *)TextData); XOSD_SetActiveBank(&Osd, Gcindex, 0, 0, 0, 0); } ``` ##圖文疊加模組 ```c void OsdDrawText(int Gcindex,int x_pos, int y_pos, int color, int string_index, int text_size) { u32 Instruction[XOSD_INS_SIZE]; u16 ObjType = XOSD_INS_OPCODE_BOXTXT; /* A text string XOSD_INS_OPCODE_TXT*/ u8 ObjSize = (text_size<<4); /* Text Scale factor (1x, 2x, 4x, 8x) */ u16 XStart = x_pos; /* Horizontal start pixel of the text */ u16 YStart = y_pos; /* Vertical start line of the text */ u16 XEnd = x_pos; /* Horizontal end pixel of the text (not used) */ u16 YEnd = y_pos; /* Vertical end line of the text (must be same as YStart) */ u8 TextIndex = string_index; /* Index of Text String */ u8 ColorIndex = color; /* Color used to draw text */ XOSD_CreateInstruction(&Osd, Instruction, Gcindex,ObjType, ObjSize, XStart, YStart, XEnd, YEnd,TextIndex, ColorIndex); XOSD_LoadInstructionList(&Osd, Gcindex, 0, Instruction, 1); return; } ``` #實現結果 前面只給出了兩個圖層,工程退不回去了,目前工程實現的是疊加8個圖層(1個視訊,7個內部影象控制器)。 #參考連結 百度網盤原始碼以及參考文件連結如下 ![](https://imgkr.cn-bj.ufileos.com/accd3d71-22a8-41a6-afdf-95c35fc569