海思HiFB开发示例及rgb转argb

一、介绍:

海思有两个FB 分别是/dev/fb0, /dev/fb3 我将fb0理解为画图层,而fb0为鼠标层。也就是osd界面可以绘制在fb0上,鼠标绘制可以在fb3上,而且海思还提供了TDE(Two Dimensional Engine)。
TDE即为利用硬件为 OSD(On Screen Display)和 GUI
(Graphics User Interface)提供快速的图形绘制功能,主要有快速位图搬移、快速色彩
填充、快速抗闪搬移、快速位图缩放、画点、画水平/垂直线、位图格式转换、位图
alpha 叠加、位图按位布尔运算、ColorKey 操作。为界面表现的提高提供了底层硬件支持。
需要注意的是要操作海思的fb需要先初始化VO模块。

二、示例

本实例利用 PAN_DISPLAY 连续显示 15 幅分辨率为 640×352 的图片,以达到动态显
示的效果。
每个文件存储的都是象素格式为 ARGB1555 的纯数据(不包含附加信息的图像数据)

#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include "hifb.h"
#define IMAGE_WIDTH 640
#define IMAGE_HEIGHT 352
#define IMAGE_SIZE (640*352*2)
#define IMAGE_NUM 14
#define IMAGE_PATH "./res/%d.bits"
static struct fb_bitfield g_r16 = {10, 5, 0};
static struct fb_bitfield g_g16 = {5, 5, 0};
static struct fb_bitfield g_b16 = {0, 5, 0};
static struct fb_bitfield g_a16 = {15, 1, 0};
int main()
{
int fd;
int i;
struct fb_fix_screeninfo fix;
struct fb_var_screeninfo var;
unsigned char *pShowScreen;
unsigned char *pHideScreen;
HIFB_POINT_S stPoint = {40, 112};
FILE *fp;
VO_PUB_ATTR_S stPubAttr = {0};
char image_name[128];
/*0. open VO device 0 */
/* …… initialize the attributes for stPubAttr */
HI_MPI_VO_SetPubAttr(0, &stPubAttr);
HI_MPI_VO_Enable(0);
/*1. open Framebuffer device overlay 0*/
fd = open("/dev/fb0", O_RDWR);
if(fd < 0)
{
printf("open fb0 failed!\n");
return -1;
}
/*2. set the screen original position*/
if (ioctl(fd, FBIOPUT_SCREEN_ORIGIN_HIFB, &stPoint) < 0)
{
printf("set screen original show position failed!\n");
return -1;
}
/*3. get the variable screen info*/
if (ioctl(fd, FBIOGET_VSCREENINFO, &var) < 0)
{
printf("Get variable screen info failed!\n");
close(fd);
return -1;
}
/*4. modify the variable screen info
the screen size: IMAGE_WIDTH*IMAGE_HEIGHT
the virtual screen size: IMAGE_WIDTH*(IMAGE_HEIGHT*2)
the pixel format: ARGB1555
*/
var.xres = var.xres_virtual = IMAGE_WIDTH;
var.yres = IMAGE_HEIGHT;
var.yres_virtual = IMAGE_HEIGHT*2;
var.transp= g_a16;
var.red = g_r16;
var.green = g_g16;
var.blue = g_b16;
var.bits_per_pixel = 16;
/*5. set the variable screeninfo*/

/*这里设置了fb的像素格式为ARGB1555*/

if (ioctl(fd, FBIOPUT_VSCREENINFO, &var) < 0)
{
printf("Put variable screen info failed!\n");
close(fd);
return -1;
}
/*6. get the fix screen info*/
if (ioctl(fd, FBIOGET_FSCREENINFO, &fix) < 0)
{
printf("Get fix screen info failed!\n");
close(fd);
return -1;
}
/*7. map the physical video memory for user use*/
pShowScreen = mmap(NULL, fix.smem_len, PROT_READ|PROT_WRITE,MAP_SHARED, fd, 0);
pHideScreen = pShowScreen + IMAGE_SIZE;
memset(pShowScreen, 0, IMAGE_SIZE);
/*8. load the bitmaps from file to hide screen and set panel display the
hide screen*/
for(i = 0; i < IMAGE_NUM; i++)
{
sprintf(image_name, IMAGE_PATH, i); //"./res/0.bits" "./res/1.bits" ...
fp = fopen(image_name, "rb");
if(NULL == fp)
{
printf("Load %s failed!\n", image_name);
close(fd);
return -1;
}
//一次性读取整个图像
fread(pHideScreen, 1, IMAGE_SIZE, fp);
fclose(fp);
usleep(10);
if(i%2) //使用一个双显存的切换模式
{//奇数帧存储到pShowScreen + 0 起始 的buffer中
//奇数帧只需将显存buffer的y帧偏移回0 位置即可。
var.yoffset = 0;
pHideScreen = pShowScreen + IMAGE_SIZE;
}
else
{//偶数帧存储到pShowScreen + IMAGE_SIZE 起始的buffer中
 //偶数帧显示只需将显存buffer的y轴偏移IMAGE_HEIGHT即可
var.yoffset = IMAGE_HEIGHT;
pHideScreen = pShowScreen;
}
if (ioctl(fd, FBIOPAN_DISPLAY, &var) < 0)
{
printf("FBIOPAN_DISPLAY failed!\n");
close(fd);
return -1;
}
}
printf("Enter to quit!\n");
getchar();
/*9. close the devices*/
close(fd);
HI_MPI_VO_Disable(0);
return 0;
}

这个例子不够通用,由于当前设置了海思framebuffer的像素格式为ARGB1555,故当我们想要显示一幅bmp 图像 rgb888的图像时我们需要做像素转换
附上 bmp转argb1555的代码

	typedef struct hiOSD_COMPONENT_INFO_S{

		int alen;
		int rlen;
		int glen;
		int blen;
	}OSD_COMP_INFO;

	OSD_COMP_INFO s_OSDCompInfo[OSD_COLOR_FMT_BUTT] = {{0, 4, 4, 4},   /*RGB444*/
														{4, 4, 4, 4},   /*ARGB4444*/
														{0, 5, 5, 5},   /*RGB555*/
														{0, 5, 6, 5},   /*RGB565*/
														{1, 5, 5, 5},   /*ARGB1555*/
														{0, 0, 0, 0},   /*RESERVED*/
														{0, 8, 8, 8},   /*RGB888*/
														{8, 8, 8, 8}    /*ARGB8888*/
														};
	inline unsigned short OSD_MAKECOLOR_U16(unsigned char r, unsigned char g, unsigned char b, OSD_COMP_INFO compinfo)
	{
		unsigned char r1, g1, b1;
		unsigned short pixel = 0;
		unsigned int tmp = 15;

		r1 = g1 = b1 = 0;
		r1 = r >> (8 - compinfo.rlen);
		g1 = g >> (8 - compinfo.glen);
		b1 = b >> (8 - compinfo.blen);
		while(compinfo.alen)
		{
			pixel |= (1 << tmp);
			tmp --;
			compinfo.alen--;
		}
		
		pixel |= (r1 | (g1 << compinfo.blen) | (b1 << (compinfo.blen + compinfo.glen)));
		return pixel;
	}
	void draw_pixel_on_fb(int x, int y, unsigned int rgb)
	{
		unsigned char r, g, b;
		if (m_fb)
		{
				//printf("argb1555\n");
				r = (((unsigned int)(rgb)) & 0xFF);
				g = (((unsigned int)(rgb)) & 0xFF00) >> 8;
				b = (((unsigned int)(rgb)) & 0xFF0000) >> 16;
				((unsigned short*)m_phy_fb)[y * (m_display->get_width()) + x] = OSD_MAKECOLOR_U16(r,g,b,s_OSDCompInfo[4]) ; //往fb单像素中写值
		}
	}	

TDE的具体用法我还没研究,有兴趣请留言点赞。谢谢。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值