3559A sample hifb解析

3559A sample hifb解析_第1张图片
这个就是主程序的5个选择模式,其实大同小异,我们主要分析一下第一种标准模式的。

3559A sample hifb解析_第2张图片


这个部分我们看到,其实就是初始化海思的sys和Vo,不是我们关注的重点,

3559A sample hifb解析_第3张图片
海思的图像层和输出设备以及设备文件之间的绑定关系是这个样子的,所以我们也要对应起来。因为例子内部我们用到的是fb0,所以对应着g0和dhd0。这个是固定绑定关系,无需我们额外操作。


3559A sample hifb解析_第4张图片
这个是开启了两个线程,分别做不同的事情,相关的参数解释上面也有,比较容易看懂。


进入到SAMPLE_HIFB_PANDISPLAY这个线程当中,我们看看里面都有些什么。算了直接上代码,上面有代码解析。
    /********************************
    * Step 1. open framebuffer device overlay 0
    **********************************/
    pstInfo->fd = open(file, O_RDWR, 0);//打开对应的设备
    if (pstInfo->fd < 0)
    {
        SAMPLE_PRT("open %s failed!\n", file);
        return HI_NULL;
    }

    bShow = HI_FALSE;
    if (ioctl(pstInfo->fd, FBIOPUT_SHOW_HIFB, &bShow) < 0)//显示或隐藏该叠加层(此处为隐藏)
    {
        SAMPLE_PRT("FBIOPUT_SHOW_HIFB failed!\n");
        return HI_NULL;
    }
    /********************************
    * Step 2. set the screen original position
    **********************************/
    /* 2. set the screen original position */
    switch(pstInfo->ctrlkey)
    {
        case 3:
        {
            stPoint.s32XPos = 150;
            stPoint.s32YPos = 150;
        }
        break;
        default:
        {
            stPoint.s32XPos = 0;
            stPoint.s32YPos = 0;
        }
    }
    
    /*设置叠加层在屏幕上显示的起始点坐标*/
    if (ioctl(pstInfo->fd, FBIOPUT_SCREEN_ORIGIN_HIFB, &stPoint) < 0)
    {
        SAMPLE_PRT("set screen original show position failed!\n");
        close(pstInfo->fd);
        return HI_NULL;
    }

    /********************************
    * Step 3. get the variable screen information
    获取屏幕的可变信息
    **********************************/
    if (ioctl(pstInfo->fd, FBIOGET_VSCREENINFO, &var) < 0)
    {
        SAMPLE_PRT("Get variable screen info failed!\n");
        close(pstInfo->fd);
        return HI_NULL;
    }

    /* **********************************************************
    *Step 4. modify the variable screen info//改变可变信息
    *the screen size: IMAGE_WIDTH*IMAGE_HEIGHT//屏幕大小=宽*高
    * the virtual screen size: VIR_SCREEN_WIDTH*VIR_SCREEN_HEIGHT//虚拟
    *(which equals to VIR_SCREEN_WIDTH*(IMAGE_HEIGHT*2))
    *the pixel format: ARGB1555
    **************************************************************/
    SAMPLE_PRT("[Begin]\n");
    SAMPLE_PRT("wait 4 seconds\n");
    usleep(4 * 1000 * 1000);

    switch (enClrFmt = pstInfo->enColorFmt)
    {
        //像素格式为argb8888,就是占4个字节,分别对应alp green...
        case HIFB_FMT_ARGB8888:
            var.transp = s_a32;
            var.red    = s_r32;
            var.green  = s_g32;
            var.blue   = s_b32;
            var.bits_per_pixel = 32;
            u32Color         = HIFB_RED_8888;
            enTdeClrFmt      = TDE2_COLOR_FMT_ARGB8888;
            g_osdColorFmt    = OSD_COLOR_FMT_RGB8888;
            break;
        default:
            var.transp = s_a16;
            var.red    = s_r16;
            var.green  = s_g16;
            var.blue   = s_b16;
            var.bits_per_pixel = 16;
            enClrFmt         = HIFB_FMT_ARGB1555;
            u32Color         = HIFB_RED_1555;
            enTdeClrFmt     = TDE2_COLOR_FMT_ARGB1555;
            break;
    }
    u32BytePerPixel    = var.bits_per_pixel/8;//因为是argb8888所以是32/8 如果是argb1555 16/8
    printf("u32BytePerPixel=%d\n", u32BytePerPixel);//这个的意思就是一个像素占几个字节
    switch(pstInfo->ctrlkey)
    {
        //{0,1,2,3}={1buffer, 2buffer, 0buffer pan display, 0buffer refresh}
        case 3://如果扩展参数为
        {
            var.xres_virtual = 48;//长,宽
            var.yres_virtual = 48;
            var.xres = 48;
            var.yres = 48;
        }
        break;
        default:
        {
            var.xres_virtual = u32Width;
            var.yres_virtual = u32Height * u32BytePerPixel;
            printf("var.yres_virtual=%d\n", var.yres_virtual);//其实就是最后一行的位置
            var.xres         = u32Width;
            var.yres         = u32Height;
        }
    }

    var.activate       = FB_ACTIVATE_NOW;

    /*********************************
    * Step 5. set the variable screen information
    ***********************************/
    if (ioctl(pstInfo->fd, FBIOPUT_VSCREENINFO, &var) < 0)//设置可变参数
    {
        SAMPLE_PRT("Put variable screen info failed!\n");
        close(pstInfo->fd);
        return HI_NULL;
    }

    /**********************************
    * Step 6. get the fix screen information
    ************************************/
    //获取固定参数
    if (ioctl(pstInfo->fd, FBIOGET_FSCREENINFO, &fix) < 0)
    {
        SAMPLE_PRT("Get fix screen info failed!\n");
        close(pstInfo->fd);
        return HI_NULL;
    }
    u32FixScreenStride = fix.line_length;   /*fix screen stride*///最后一列的位置
    printf("u32FixScreenStride = fix.line_length=%d\n", u32FixScreenStride = fix.line_length);
    /***************************************
    * Step 7. map the physical video memory for user use
    ******************************************/
#ifdef __HuaweiLite__
    pShowScreen = fix.smem_start;
#else
    //把屏幕地址映射出来
    pShowScreen = mmap(HI_NULL, fix.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, pstInfo->fd, 0);
    if (MAP_FAILED == pShowScreen)
    {
        SAMPLE_PRT("mmap framebuffer failed!\n");
        close(pstInfo->fd);
        return HI_NULL;
    }
#endif
    //清空屏幕
    memset(pShowScreen, 0x0, fix.smem_len);

    /* time to play*/
    bShow = HI_TRUE;
    if (ioctl(pstInfo->fd, FBIOPUT_SHOW_HIFB, &bShow) < 0)//显示出来(显示只看到背景)
    {
        SAMPLE_PRT("FBIOPUT_SHOW_HIFB failed!\n");
#ifndef __HuaweiLite__
        munmap(pShowScreen, fix.smem_len);
#endif
        close(pstInfo->fd);
        return HI_NULL;
    }
    #if 1
    /* Only for G0 or G1 */
    if (GRAPHICS_LAYER_G0 == pstInfo->layer || GRAPHICS_LAYER_G1 == pstInfo->layer)
    {
        for (i = 0; i < 1; i++)
        {
            if (i % 2)
            {
                var.yoffset = var.yres;
            }
            else
            {
                var.yoffset = 0;
            }
            //此处画出一个红色的box
            ptemp = (pShowScreen + var.yres * u32FixScreenStride * (i % 2));//当前显示地址+当前显示内存大小
            for (y = 100; y < 300; y++)//从100列开始  画长度300
            {
                for (x = 0; x < 300; x++)//从0行开始  画长度300
                {
                    if (HIFB_FMT_ARGB8888 == enClrFmt)
                    {
                        *((HI_U32*)ptemp + y * var.xres + x) = HIFB_RED_8888;
                    }else
                    {
                        *((HI_U16*)ptemp + y * var.xres + x) = HIFB_RED_1555;
                    }
                }
            }
            /*
            * Note : Not acting on ARGB8888, for ARGB8888 format image's alpha, you can change ptemp[x][y]'s value
            * HIFB_RED_8888 = 0xffff00000 means alpha=255(show),red.0x00ff0000 means alpha=0,red(hide).
            */
            SAMPLE_PRT("expected: the red box will appear!\n");
            sleep(2);
            //这些设置alp对rgb8888并不起作用
            stAlpha.bAlphaEnable = HI_TRUE;
            /*Alpha0 值,范围 0~255,默认为 255。在 RGB1555 格式
            下,当最高位为 0 时,选择该值作为 Alpha 叠加的 Alpha
            值。*/
            stAlpha.u8Alpha0     = 0x0;
            /*Alpha1 值,范围 0~255,默认为 255。在 RGB1:5:5:5 格式
            下,当最高位为 1 时,选择该值作为 Alpha 叠加的 Alpha
            值。*/
            stAlpha.u8Alpha1     = 0x0;

            //也就是选择当前alp0=0x0 为叠加通道的透明度值,透明
            if (ioctl(pstInfo->fd, FBIOPUT_ALPHA_HIFB,  &stAlpha) < 0)
            {
                SAMPLE_PRT("Set alpha failed!\n");
                close(pstInfo->fd);
                return HI_NULL;
            }
            SAMPLE_PRT("expected: after set alpha = 0, the red box will disappear!\n");
            sleep(2);

            stAlpha.u8Alpha0 = 0;
            stAlpha.u8Alpha1 = 0xFF;
            //不透明
            if (ioctl(pstInfo->fd, FBIOPUT_ALPHA_HIFB,  &stAlpha) < 0)
            {
                SAMPLE_PRT("Set alpha failed!\n");
                close(pstInfo->fd);
                return HI_NULL;
            }
            SAMPLE_PRT("expected:after set set alpha = 0xFF, the red box will appear again!\n");
            sleep(2);

            SAMPLE_PRT("expected: the red box will erased by ----------------------------colorkey!\n");
            stColorKey.bKeyEnable = HI_TRUE;
            stColorKey.u32Key     = (enClrFmt==HIFB_FMT_ARGB8888 ? HIFB_RED_8888 : HIFB_RED_1555);
            //HIFB_RED_1555 0xFC00  1111110000000000  对应r值都为1,也就是透过红色
            s32Ret = ioctl(pstInfo->fd, FBIOPUT_COLORKEY_HIFB, &stColorKey);//使用此接口设置当前叠加层的 colorkey 功能
            if (s32Ret < 0)
            {
                SAMPLE_PRT("FBIOPUT_COLORKEY_HIFB failed!\n");
                close(pstInfo->fd);
                return HI_NULL;
            }
            sleep(2);
            SAMPLE_PRT("expected: the red box will appear again!\n");
            stColorKey.bKeyEnable = HI_FALSE;
            s32Ret = ioctl(pstInfo->fd, FBIOPUT_COLORKEY_HIFB, &stColorKey);//关闭关键色
            if (s32Ret < 0)
            {
                SAMPLE_PRT("FBIOPUT_COLORKEY_HIFB failed!\n");
                close(pstInfo->fd);
                return HI_NULL;
            }
            sleep(2);
        }
    }
    #endif

    sleep(10);
    /* show bitmap */
    switch (pstInfo->ctrlkey)
    {
        /* 2 means none buffer and just for pan display.*/
        case 2:
        {
            /*change bmp*/
            printf("--------------------------------------\n");
            //打开mmz内存
            if (HI_FAILURE == HI_MPI_SYS_MmzAlloc(&g_Phyaddr, ((void**)&Viraddr),
                                                  NULL, NULL, 1920 * 1080 * u32BytePerPixel))
            {
                SAMPLE_PRT("allocate memory (maxW*maxH*%d bytes) failed\n",u32BytePerPixel);
                close(pstInfo->fd);
                return HI_NULL;
            }

            s32Ret = HI_TDE2_Open();
            if (s32Ret < 0)
            {
                SAMPLE_PRT("HI_TDE2_Open failed :%d!\n", s32Ret);
                HI_M

你可能感兴趣的:(海思#例程)