zoukankan      html  css  js  c++  java
  • 视频处理之OSD

    欲观原文,请君移步

    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

    下面小编会详细介绍OSD IP的例化与使用

    3 OSD PL端

    如果在使用OSD IP过程中出现如下错误,请在xilinx官网上申请OSD的License,这里不再详述如何申请License。

    首先在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

    点击Screen Layout Options,如图3所示

    (1) Background size(选择背景大小)里宽度输入1920,高度输入1080

    (2) Background color输入背景颜色,这里选择黑色,可以通过axi-lite来控制

    (3) layer0因为选择的是外部视频流,所以比如设置为外部视频流分辨率,输错了,可能无法正常使用,小编已经遇到过了,本文使用1920x1080外部视频流

    (4) layer1因为选择的是内部图像控制器,所以无所谓设置什么,可以通过axi-lite控制,所以选择默认即可

    图3

    点击LAYER 1 Options出现图4界面:因为是内部图像控制器,所以可以进行一些配置,比如颜色多少,字符数目,比特像素等等,这里小编选择的是默认。

    图4

    配置完OSD IP后,将其AXI-lite挂在总线上即可,然后保存Block Design即可。

    注:点开Address Editor,一定要确定该IP被分配地址空间,如果没有,点击一下自动分配(小编遇到的问题就是这个ip地址空间在unmap里,导致后续PS端OSD IP无法初始化)。

    图4

    4 OSD PS端

    下面就是常规操作include bitstream导出SDK,其实就是生成hdf文件,硬件信息。然后就launch SDk。如图4所示,可以看到hdf文件里都有什么。

    图4

    新建一个design_top的空工程,如图5所示,在design_top_bsp下面可以看到system.mss文件,在红框中找到OSD IP。

    图5

    点击import examples,出现如图6所示,勾选对话框后选择OK(不会玩IP先整个example)。
    图6

    打开XosdSelfTestExample.c即可看到该例子程序是怎么个处理流程(图7为main函数,图8为使用流程)小编称之为PS端IP使用三步法

    • 第一步先进行lookup该IP

    • 第二步就是初始化该IP

    • 第三步就是使用IP

    图7

    图8

    运行一下,结果如图9所示,可以看到UART会打印OSD成功信息。

    图9

    OSD 实例

    闲话不说,上面经过了OSD example,小编也作为一个PS端初学者来玩一玩。

    尴尬的是经常在写c代码的时候想着写begin...end,真是verilog写习惯了,思想难以改变,原来是花括弧啊{}

    初始化模块如下

    在初始化后必须将该模块进行复位,然后,否则该IP启动不了。

    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);

    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);
    }
    

    图文叠加模块

    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个内部图像控制器)。

    参考链接

    百度网盘源码以及参考文档链接如下

  • 相关阅读:
    UVA 10618 Tango Tango Insurrection
    UVA 10118 Free Candies
    HDU 1024 Max Sum Plus Plus
    POJ 1984 Navigation Nightmare
    CODEVS 3546 矩阵链乘法
    UVA 1625 Color Length
    UVA 1347 Tour
    UVA 437 The Tower of Babylon
    UVA 1622 Robot
    UVA127-"Accordian" Patience(模拟)
  • 原文地址:https://www.cnblogs.com/xiguazai/p/13047733.html
Copyright © 2011-2022 走看看