免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1804 | 回复: 0
打印 上一主题 下一主题

HI3110E平台集成UEI多功能3D遥控器 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-08-30 21:35 |只看该作者 |倒序浏览

四、基于标准鼠标设备porting层的开发
思路:1)要让cursor在电视上显示,不可能跟osd是在同一层面,应该是在osd层的前面一层,上网查资料,仔细分析海提供的底层API文档。
      2)各个层面显示顺序该怎么定?
      3)视频、图像输出的接口调用顺序该怎么定?
      4)YCbCr与RGB有什么区别?
      5)cursor在电视里显示后,该怎么将usb设备消息向上层传递,然后传向ipanel中间件?
      6)通过移动遥控器,会在X\Y方向有偏移量,位置在变换,怎么样让鼠标图标在电视里跟着移动?
1、VO显示子平面
一般的显示平面由以下五个部分组成:

Cursor:光标输出平面
Osd0:软件产生的图形输出平面,如菜单
Video Display:解码后的视频输出平面
Osd1:软件产生的图形输出平面,如菜单
Background:视频的背景颜色输出平面

其中cursor平面位置在最前面,其后依次是OSD0、Video Display以及osd1,最后是Background平面,osd0、Video Display以及osd1平面可以任意交换位置,前面的平面可以遮住后面的平面,并通过Mixer模块实现多个平面之间的ALPHA融合。

2.在porting层创建ipanel_usb.c文件
创建usb设备初始化函数USB_Init(),对设备做初始化工作。
3、打开VO设备
     HI_UNF_DISPLAY_OPEN();
4、打开总的输出层,只有调用此接口后,才能调用其它接口
     HI_UNF_DISPLAY_SetEnable(HI_TRUE);
4、  设置硬件鼠标层在第0层显示,从里往外依次是:BACKGROUND STILL VIDEO_DISPLAY OSD  CUROSR
HI_UNF_DISPLAY_SetLayerOrder(HI_UNF_DISPLAY_LAYER_HC,0)
5、  初始化工作,装载Cursor参数
InsPara.pBmp = bitMapData_cursor_1;--------------------鼠标位图数据
       InsPara.pClut = cursor_yuv16_1;--------鼠标颜色调色版,支持16种颜色,海思3110e盒子规定的cursor为16色
       InsPara.u32Alpha = 255;
       InsPara.sPosition.u32StX = 100;
       InsPara.sPosition.u32StY = 100;
       InsPara.sPosition.u32BaseWidth = 720;
       InsPara.sPosition.u32BaseHeight = 576;
HI_CURSOR_InstallPara(&InsPara);----------装载调色板参数
              
6、  使能图形接口,打开硬件鼠标层
HI_UNF_DISPLAY_EnableLayer(HI_UNF_DISPLAY_LAYER_HC);

此时我们需要创建另外一个线程USB_Thread()来打开设备,读设备上的消息,并传给上层。

7、  在线程USB_Thread()中
a)         先打开hid设备
fd = open("/dev/input/event0", O_RDWR);
b)        然后循环读设备上的数据,根据第一部分对input系统的描述。
        read(fd, &event, sizeof(struct input_event));读出的消息全部保存在event结构中。
event.code == 1表示是Y轴方向,event.value就是移动遥控器Y轴方向的偏移量
event.code == 0表示是Y轴方向,event.value就是移动遥控器X轴方向的偏移量
然后我们每移动一次遥控,就需要将这个偏移量重新赋给InsPara.sPosition

c)        重新设置坐标位置
HI_CURSOR_SetPosition(&InsPara.sPosition);
d)        显示Cursor
HI_CURSOR_Show();
e)         将鼠标消息传向上层
Ipanel_porting_event.h里面定义了鼠标各种消息事件。
                 #define EISPUTUSBMESSAGE(a,b) send_message_to_tail_net(me, IPANEL_EVENT_TYPE_MOUSE, a, b)
                 IPANEL_EVENT_TYPE_MOUSE:为ipanel规定的鼠标事件
              a:鼠标子事件,例如:
              b:扩展消息
enum
{
                           EIS_MOUSE_NONE,
                           EIS_MOUSE_MOUSEMOVE,//鼠标移动
                           EIS_MOUSE_LBUTTONDOWN,//鼠标左键按下
                           EIS_MOUSE_LBUTTONUP,//鼠标左键弹起
EIS_MOUSE_MBUTTONDOWN,//鼠标中间按下
EIS_MOUSE_MBUTTONUP,//鼠标中建弹起
                           EIS_MOUSE_RBUTTONDOWN,//鼠标右键按下
                           EIS_MOUSE_RBUTTONUP,//鼠标右键弹起
EIS_MOUSE_LBUTTONDCLICK,//鼠标左键双击
EIS_MOUSE_RBUTTONDCLICK,//鼠标右键双击
                           EIS_MOUSE_UNDEFINED
};

void send_message_to_tail_net(PortManager *me, unsigned int e0, unsigned int e1, unsigned int e2)
{
    BrwEvent *pEvent;
    int err = 0;
    if (!me) return;
    pthread_mutex_lock(&me->queuemutex);
    if (!me->queusehead_net)
    {
        pEvent = me->queidlehead_net;
        me->queidlehead_net = me->queidlehead_net->next;
        pEvent->next = NULL;
        pEvent->event[0] = e0;
        pEvent->event[1] = e1;
        pEvent->event[2] = e2;
        me->queusehead_net = pEvent;
        me->queusetail_net = pEvent;
        pthread_cond_signal(&me->queuecond);
    }
    else
    {
        if (me->queidlehead_net)
        {
            pEvent = me->queidlehead_net;
            me->queidlehead_net = me->queidlehead_net->next;
            pEvent->next = NULL;
            if (!me->queidlehead_net) me->queidletail_net = NULL;
            pEvent->event[0] = e0;
            pEvent->event[1] = e1;
            pEvent->event[2] = e2;
            me->queusetail_net->next = pEvent;
            me->queusetail_net = pEvent;
        }
        else
            err = 1;
    }
    pthread_mutex_unlock(&me->queuemutex);
if (err)
IPANEL_DEBUG("####Lost Event: %d %d %d####\n", e0, e1, e2);
}   

8、  在ipaneldtv_task.c中,由ipanel_proc(handle, (int)event[0], event[1], event[2]);将鼠标消息传给中间件。

总结:在电视里显示鼠标时,先自己写一个循环,让x、y的偏移量分别变化,测试鼠标图标是否在电视上循环跳动。如果测试成功,这样在USB_Thread线程中,像循环一样,将不断移动遥控器时x、y的偏移量值重新赋给调色板中的InsPara.sPosition.u32StX,InsPara.sPosition.u32StY,然后重新设置位置再显示,这样实现效率比较高。


五、制作鼠标图标
1、在windows下制作鼠标图标,格式为bmp格式。
2、根据bmp格式文档解析,得出File Size、Bits Per Pixer(每个像素的大小)等等。解析出每个像素占16位(两个字节)
1、  用UE打开,去掉里面的头文件,由于hi3110e的cursor大小为40*40,所以我们需要将其位图数据转换为一个40*40的大数组。
2、  由于每个像素占两个字节,为了方便,可以将ff7f全换成1,1f7c全换成0,转换为40*40的数组后,可以大概的看到是一个倒立的鼠标箭头形状,然后将前后的行分别互换,这样就成了一个正立的箭头形状。
5、将数组放到unsigned int bitMapData_cursor_1[] = {}中编译,在电视里看到不是正规的鼠标图标,这时我们需要将每个数组中的每个元素的高低位互换。编译后在电视里显示就是个正规的鼠标图标了。
6、由于背景色是红色,我们希望在电视里看到的鼠标图标,其他的都需要是透明色。我们需要根据YCbCr的格式来测试:
Alpha (8bit) + Y(8bit) +Cb(8Bit) + Cr(8Bit)
HI_U32  cursor_yuv16_1[16] =
{
0x80808b80,
0x805b61ed,
0x80389e25,
0x8013df91,
0x80ed386f,
0x80c87adb,
0x80a5b713,
0x8080eb80,
0x804eaea2,
0x8097993c,
0x8084bb99,
0x80a44cad,
0x80801f80,
0x806e40b6,
0x80ba5bb7,
0xff6eab42
};
对于这个调色板来说,前面八位要么ff是全透明,要么00是全透明,经过测试,00是全透明。那么将调色板改成如下:
HI_U32  cursor_yuv16_1[16] =
{
   0x00000000,  
   0xff5b61ed,
   0xff389e25,
   0xff13df91,
   0xffed386f,
   0xffc87adb,
   0xffa5b713,
   0xff80eb80,
   0xff4eaea2,
   0xff97993c,
   0xff84bb99,
   0xffa44cad,
   0xff801f80,
   0xff6e40b6,
   0xffba5bb7,
   0xff6eab42,
};
这样在电视里看到的就只是一个正规的鼠标图标(箭头形状、手形、沙漏形、I字形)。
   


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/100746/showart_2041635.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP