Chinaunix首页 | 论坛 | 博客
  • 博客访问: 34826
  • 博文数量: 13
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 150
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-11 11:28
文章分类

全部博文(13)

文章存档

2011年(1)

2009年(12)

我的朋友
最近访客

分类:

2009-07-11 11:43:24

引脚的定义不同,然后我们改用新文档里的GPIO_B  3   GPIO_G 3,重新编译调试,这次终于可以捕捉到中断了。

总结:这部分耽误了不少时间,碰到了问题不能总停留在一个点上,想方设法从其他角度考虑,尽快找出问题的根本所在,避免影响项目进度。

 

四、基于标准鼠标设备porting层的开发

思路:1)要让cursor在电视上显示,不可能跟osd是在同一层面,应该是在osd层的前面一层,上网查资料,仔细分析海提供的底层API文档。

      2)各个层面显示顺序该怎么定?

      3)视频、图像输出的接口调用顺序该怎么定?

      4YCbCrRGB有什么区别?

      5cursor在电视里显示后,该怎么将usb设备消息向上层传递,然后传向ipanel中间件?

      6)通过移动遥控器,会在X\Y方向有偏移量,位置在变换,怎么样让鼠标图标在电视里跟着移动?

1VO显示子平面

一般的显示平面由以下五个部分组成:

 

Cursor:光标输出平面

Osd0:软件产生的图形输出平面,如菜单

Video Display:解码后的视频输出平面

Osd1:软件产生的图形输出平面,如菜单

Background:视频的背景颜色输出平面

 

其中cursor平面位置在最前面,其后依次是OSD0Video Display以及osd1,最后是Background平面,osd0Video 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盒子规定的cursor16

       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]);将鼠标消息传给中间件。

 

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

 

 

五、制作鼠标图标

1、在windows下制作鼠标图标,格式为bmp格式。

2、根据bmp格式文档解析,得出File SizeBits Per Pixer(每个像素的大小)等等。解析出每个像素占16位(两个字节)

1、  UE打开,去掉里面的头文件,由于hi3110ecursor大小为40*40,所以我们需要将其位图数据转换为一个40*40的大数组。

2、  由于每个像素占两个字节,为了方便,可以将ff7f全换成11f7c全换成0,转换为40*40的数组后,可以大概的看到是一个倒立的鼠标箭头形状,然后将前后的行分别互换,这样就成了一个正立的箭头形状。

5、将数组放到unsigned int bitMapData_cursor_1[] = {}中编译,在电视里看到不是正规的鼠标图标,这时我们需要将每个数组中的每个元素的高低位互换。编译后在电视里显示就是个正规的鼠标图标了。

6、由于背景色是红色,我们希望在电视里看到的鼠标图标,其他的都需要是透明色。我们需要根据YCbCr的格式来测试:

Alpha 8bit + Y8bit +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字形)。

  

阅读(1084) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~