精华内容
下载资源
问答
  • 按照手册中的说明,使用区域管理功能需要做如下几步 1.用户填充区域属性并创建区域 2.将该区域指定到具体通道中(如VENC)。在指定到具体通道时,需要输入通道的显示属性 之后用户可以通过以下操作来控制区域属性,...

    按照手册中的说明,使用区域管理功能需要做如下几步
    1.用户填充区域属性并创建区域
    2.将该区域指定到具体通道中(如VENC)。在指定到具体通道时,需要输入通道的显示属性
        之后用户可以通过以下操作来控制区域属性,以及在某通道的通道显示属性
        2.1通过 HI_MPI_RGN_GetAttr、 HI_MPI_RGN_SetAttr 获取和设置区域属性
        2.2通过 HI_MPI_RGN_SetBitMap(仅针对 Overlay)设置区域的位图信息
        2.3通过 HI_MPI_RGN_GetDisplayAttr 和 HI_MPI_RGN_SetDisplayAttr 获取和设置区域在某通道(如 VENC 通道)的通道显示属性。
        2.4最后用户可以将该区域从通道中撤出(非必须操作),再销毁区域。

     

    接下来我们看看每一步应该怎么做

    第一步:用户填充区域属性并创建区域

    想要创建区域,可以调用函数

    HI_MPI_RGN_Create

    来创建一个region区域,函数原型如下

    HI_S32 HI_MPI_RGN_Create(
        RGN_HANDLE Handle,                  //区域句柄号
        const RGN_ATTR_S *pstRegion         //区域属性指针
    );


    每一个区域对应一个句柄,和一个具体的属性RGN_ATTR_S,属性结构体定义如下
     

    typedef struct hiRGN_ATTR_S
    {
        RGN_TYPE_E enType;                  //区域类型
        RGN_ATTR_U unAttr;                  //区域属性
    } RGN_ATTR_S;

    区域类型有以下几种

    • OVERLAY_RGN                           //VENC通道视频叠加区域
    • COVER_RGN                               //VI通道视频叠加区域
    • COVEREX_RGN                          //扩展视频遮挡区域
    • OVERLAYEX_RGN                      //扩展视频叠加区域

    对应的区域属性就有两种

    • OVERLAY_ATTR_S      stOverlay                //VENC通道叠加区域属性
    • OVERLAYEX_ATTR_S    stOverlayEx         //扩展叠加区域属性

    这两个属性的结构体其实是一样的,以OVERLAY_ATTR_S举例,结构体定义如下
     

    typedef struct hiOVERLAY_ATTR_S
    {
        PIXEL_FORMAT_E enPixelFmt;          //OSD的像素格式,目前只支持ARGB1555,ARGB4444,ARGB8888这三种
        HI_U32 u32BgColor;                  //区域的背景色
        SIZE_S stSize;                      //区域的高宽
    }OVERLAY_ATTR_S;

    将这些属性填充好,调用HI_MPI_RGN_Create函数后,区域就创建好了,之后我们就可以通过区域句柄号进行管理

     

    第二步:将该区域指定到具体通道中

    想要指定到具体通道,可以调用函数

    HI_MPI_RGN_AttachToChn

    将区域叠加到通道上,该函数原型为

    HI_S32 HI_MPI_RGN_AttachToChn(
        RGN_HANDLE Handle,                  //区域句柄号
        const MPP_CHN_S *pstChn,            //通道结构体指针
        const RGN_CHN_ATTR_S *pstChnAttr    //区域通道显示属性指针
    );


    区域句柄我们已经有了,通道结构体指针定义如下

    typedef struct hiMPP_CHN_S
    {
        MOD_ID_E    enModId;                //模块号
        HI_S32      s32DevId;               //设备号
        HI_S32      s32ChnId;               //通道号
    } MPP_CHN_S;


    其实意思就是告诉系统,这个区域是叠加在哪个模块的哪个设备的哪个通道上面的
    区域通道显示属性指针就是用来设定区域显示属性的,结构体定义如下
     

    typedef struct hiRGN_CHN_ATTR_S
    {
        HI_BOOL           bShow;            //区域是否显示
        RGN_TYPE_E        enType;           //区域类型(OVERLAY_RGN,COVER_RGN,COVEREX_RGN,OVERLAYEX_RGN)
        RGN_CHN_ATTR_U    unChnAttr;        //区域通道显示属性(对应上面的四种类型,这个属性也有四种,具体请查阅手册)
    } RGN_CHN_ATTR_S;

    创建区域并指定到具体的通道中之后,我们的区域就已经完成了
    接下来我们就可以通过其他操作在区域里面进行显示了
    比如叠加层次,位图填充,叠加透明度等等(表8-2 Hi3516A/Hi3518EV200 region 支持的功能)

     

    这里给出一个示例Demo如下

    HI_S32 regions_Create( RGN_HANDLE RgnHandle, int width, int height, int position_x, int position_y )
    {
        HI_S32 s32Ret = HI_FAILURE;
        RGN_ATTR_S stRgnAttr;
        
        MPP_CHN_S stChn;
        RGN_CHN_ATTR_S stChnAttr;
        
        /****************************************
        step 1: create overlay regions
        ****************************************/
        stRgnAttr.enType = OVERLAYEX_RGN;
        stRgnAttr.unAttr.stOverlay.enPixelFmt = PIXEL_FORMAT_RGB_1555;
        stRgnAttr.unAttr.stOverlay.stSize.u32Width = width;
        stRgnAttr.unAttr.stOverlay.stSize.u32Height = height;
        stRgnAttr.unAttr.stOverlay.u32BgColor = 0x1f;
        RgnHandle = 0;///*域操作句柄*/
    
        s32Ret = HI_MPI_RGN_Create(RgnHandle, &stRgnAttr);
        if (HI_SUCCESS != s32Ret)
        {
    	SAMPLE_PRT("HI_MPI_RGN_Create (%d) failed with %#x!\n", RgnHandle, s32Ret);
    	return HI_FAILURE;
        }
        
        /****************************************
        step 2: attach to VPSS
        ****************************************/    
        
        stChn.enModId = HI_ID_VPSS;//HI_ID_VENC;//HI_ID_GROUP;
        stChn.s32DevId = 0;
        stChn.s32ChnId = 0;
        
        
        memset(&stChnAttr, 0, sizeof(stChnAttr));
        stChnAttr.bShow = HI_TRUE;
        stChnAttr.enType = OVERLAYEX_RGN;
        stChnAttr.unChnAttr.stOverlayExChn.stPoint.s32X = position_x;	//通道画面中显示的位置(x)
        stChnAttr.unChnAttr.stOverlayExChn.stPoint.s32Y = position_y;	//通道画面中显示的位置(Y)
        stChnAttr.unChnAttr.stOverlayExChn.u32BgAlpha = 0;  	        //OSD Alpha
        stChnAttr.unChnAttr.stOverlayExChn.u32FgAlpha = 128;
        stChnAttr.unChnAttr.stOverlayExChn.u32Layer = 0;
    
        s32Ret = HI_MPI_RGN_AttachToChn(RgnHandle, &stChn, &stChnAttr);
        if (HI_SUCCESS != s32Ret) {
    	SAMPLE_PRT("HI_MPI_RGN_AttachToChn (RgnHandle:%d, chnid:%d) failed with %#x!\n", RgnHandle, stChn.s32ChnId , s32Ret);
    	return HI_FAILURE;
        }
        
        return HI_TRUE;
    }

     

    事实上我们创建了区域以后,需要给我们的区域填充一些内容,常用的就是位图填充了,下面我们看看如何进行位图填充

     

    功能一:bmp图片进行位图填充

     

    Hi3516A的OSD只能使用位图来进行填充,如果你有一张图片,比如logo之类的,把它做成bmp格式的图片
    然后调用

    HI_S32 SAMPLE_RGN_LoadBmp

    函数先读取位图文件信息,函数原型如下

    HI_S32 SAMPLE_RGN_LoadBmp(
        const char *filename,               //文件路径
        BITMAP_S *pstBitmap,                //位图属性指针,打开的位图属性将会存放在这里
        HI_BOOL bFil,                       //暂时不关注
        HI_U32 u16FilColor                  //暂时不关注
    )


    位图文件的属性有了,我们可以调用

    HI_MPI_RGN_SetBitMap

    函数在区域里面进行位图填充,函数原型如下

    HI_S32 HI_MPI_RGN_SetBitMap(
        RGN_HANDLE Handle,                  //区域句柄号
        const BITMAP_S *pstBitmap           //位图属性指针,就是我们要进行填充的位图信息
    );


    调用之后,系统就会在根据我们之前设置的区域属性,在对应模块对应设备对应通道上面进行填充

    示例Demo如下

    HI_S32 update_regions(const char *filename, RGN_HANDLE RgnHandle, const BITMAP_S *stBitmap)
    {
        HI_S32 s32Ret = HI_FAILURE;
        
        if( HI_SUCCESS != SAMPLE_RGN_LoadBmp(filename, stBitmap, HI_FALSE, 0))
        {
    	SAMPLE_PRT("load bmp failed\n");
            return HI_FAILURE;
        }
    	    
    
        s32Ret = HI_MPI_RGN_SetBitMap(RgnHandle, stBitmap);
        if (s32Ret != HI_SUCCESS) {
    	SAMPLE_PRT("HI_MPI_RGN_SetBitMap (RgnHandle:%d) failed with %#x!\n", RgnHandle, s32Ret);
    	return HI_FAILURE;
        }
    
    
        return HI_TRUE;
    }

     

    功能二:字库文件进行位图填充

     

    有时候我们需要在图像上动态更新时间,码率等等信息,这时候如果都使用bmp图片,肯定不太合适
    那就需要把字库的点阵信息转化更位图信息,以英文字符举例


    1.打开文件

    FILE *asc16;
    
    asc16 = fopen(asc16File, "rb");
    if (asc16 == NULL )
    {
        dpf("open asc16 error!\n");
        return HI_FAILURE;
    }


    2.分配内存空间

    以8 * 16的字库举例,字库里面的8 * 16代表有8 * 16个点,但是我们要转化成位图信息就意味着,
    我们要把字库中的每个点转化为RGB格式的像素点,如果使用RGB1555格式的像素点,
    那点阵中的每一个需要占用1 + 5 + 5 + 5 = 16Bit共2个字节的大小,所以每一个字需要分配
    2 * 8 * 16大小的空间,一共有ASCNum个字就需要2 * 8 * 16 * ASCNum大小的空间

    char *FontDatabase = NULL;
    
    FontDatabase = malloc((2 * 8 * 16) * ASCNum);
    if (FontDatabase == NULL )
    {
        dpf("do malloc error!\n");
        return HI_FAILURE;
    }


        
    3.读取所有可以显示的字符,并转化为像素信息

    我们知道ASCII码可以显示的字符范围是‘ ’ ~ ‘~’,其他的是特殊字符
    所以我们需要从‘ ’开始的位置一直读取到‘~’位置为止,并将每一个点阵点转化为像素点,使用RGB1555格式
        

    HI_U16 *memp;
        
    fseek(asc16, ' ' * 16, SEEK_SET);                   //找到‘ ’开始的位置,8 * 16点阵中每一个字占用16字节的空间
    memp = (HI_U16*) FontDatabase;
    for (i = 0; i < ASCNum * 16; i++)                   //遍历所有字
    {
        ch = fgetc(asc16);                              //每次读取一行
        //显示一个字节
        for (j = 0; j < 8; j++, shortp++)               //遍历一行里面的所有点,如果是1,则转化为黑色((HI_U16)0x8000),是0则转化为白色((HI_U16)0x7fff)
        {
            if (ch & (0x01 << (7 - j)))         
                *memp = BlackPot;
            else
                *memp = WhitePot;
        }
    }


        
    4.构建位图数据

    由之前的信息我们知道,想要叠加位图需要调用函数

    HI_MPI_RGN_SetBitMap

    这个函数原型如下

    HI_S32 HI_MPI_RGN_SetBitMap(
        RGN_HANDLE Handle,                              //区域句柄号
        const BITMAP_S *pstBitmap                       //位图属性指针
    );


    区域句柄号我们创建的时候已经有了,现在需要的就是填充这个位图信息了,这个结构体原型如下

    typedef struct hiBITMAP_S
    {
        PIXEL_FORMAT_E enPixelFormat;                   //像素格式,比如555,565,1555等         
        HI_U32 u32Width;                                //图像宽度
        HI_U32 u32Height;                               //图像高度
        HI_VOID* pData;                                 //位图数据
    } BITMAP_S;

    假设我们需要显示count个字,代码应该大体是这样的
        

    void make_bitmap(const char *osdString, BITMAP_S *pstBitmap)
    {
        int locations[128] = {0};                       //存储字模的位置
        int count = 0;                                 //需要显示count个字
        int i = 0;
        int j = 0;
            
        pstBitmap->enPixelFormat = PIXEL_FORMAT_RGB_1555;    //像素格式为RGB1555
        pstBitmap->u32Width = 8 * count                     //每个字的宽度依然是8个像素点
        pstBitmap->u32Height = 16                           //每行的高度依然是16个像素点
        pstBitmap->pData = malloc(2 * 8 * 16 * count);      //点阵点转化为像素点需要的空间
            
        memset(pstBitmap->pData, 0, 2 * 8 * 16 * count);
            
        //获取要显示的字的个数和在字模中的位置
        for (i = 0; osdString[i] != '\0'; i++)
        {
            if (osdString[i] >= ' ' && osdString[i] <= '~')
            {
                locations[count] = osdString[i] - ' ';
                count++;
            }
        }
            
        //遍历所有要显示的字
        for (i = 0; i < count; i++)
        {
            //遍历每一行,一次拷贝一行即8 * 2个字节(每一个点阵点转化为像素点后占用2个字节存储)
            for (j = 0; j < 16; j++)
            {
                memcpy(
                    //展开后对应存储像素点的第j行的起始位置
                    pstBitmap->pData + j * pstBitmap->u32Width * 2,
                    //展开后对应存储点阵点的第i个字符第j行的起始位置
                    memp + (locations[i] * 2 * 8 * 16) + (16 * j),
                    16
                );
            }
        }
    }

    填充好位图信息后,我们调用HI_MPI_RGN_SetBitMap函数进行设置即可。

     

    汉字字库的方式其实是一样的,只不过汉字的位置是由区码加位码的形式来查找的,字库相关的知识可以参考HZK16汉字16*16点阵字库的使用及示例程序

    而一个16 * 16汉字点阵转化为像素点需要16 * 16 * 2的空间

    所以如果想把一个hzk16中的汉字点阵转化为像素,代码应该是这样的

    HI_U16 *memp;
        
    fseek(hzk16, location * 32, SEEK_SET);     //location代表汉字的区码+位码,16 * 16点阵中每一个字占用32字节的空间
    memp = (HI_U16*) FontDatabase;
    for (i = 0; i < 32; i++)                   //遍历这32个字节
    {
        ch = fgetc(hzk16);                              //每次读取一个字节
        //显示一个字节
        for (j = 0; j < 8; j++)               //遍历字节,如果是1,则转化为黑色((HI_U16)0x8000),是0则转化为白色((HI_U16)0x7fff)
        {
            if (ch & (0x01 << (7 - j)))         
                *memp = BlackPot;
            else
                *memp = WhitePot;
        }
    }

    如果要显示count个汉字,代码大体应该是这样的

    void make_bitmap(const char *osdString, BITMAP_S *pstBitmap)
    {
        int locations[128] = {0};                       //存储字模的位置
        int count = 0;                                 //需要显示count个字
        int i = 0;
        int j = 0;
            
        pstBitmap->enPixelFormat = PIXEL_FORMAT_RGB_1555;    //像素格式为RGB1555
        pstBitmap->u32Width = 16 * count                     //每个字的宽度依然是16个像素点
        pstBitmap->u32Height = 16                            //每行的高度依然是16个像素点
        pstBitmap->pData = malloc(2 * 16 * 16 * count);       //点阵点转化为像素点需要的空间
            
        memset(pstBitmap->pData, 0, 2 * 16 * 16 * count);
            
        //获取要显示的字的个数和在字模中的位置
        for (i = 0; osdString[i] != '\0'; i++)
        {
            if (osdString[i] >= 0xa1 && osdString[i + 1] >= 0xa1)
            {
                locations[osdLen] = (osdString[i] - 0xa1) * 94 + (osdString[i + 1] - 0xa1);
                count++;
                i++;
            }
        }
            
        //遍历所有要显示的字
        for (i = 0; i < count; i++)
        {
            //遍历每一行,一次拷贝一行即16 * 2个字节(每一个点阵点转化为像素点后占用2个字节存储)
            for (j = 0; j < 16; j++)
            {
                memcpy(
                    //展开后对应存储像素点的第j行的起始位置
                    pstBitmap->pData + j * pstBitmap->u32Width * 2,
                    //展开后对应存储点阵点的第i个字符第j行的起始位置
                    memp + (locations[i] * 2 * 16 * 16) + (32 * j),
                    32
                );
            }
        }
    }

    同样的,填充好位图信息后,我们调用HI_MPI_RGN_SetBitMap函数进行设置即可。

     

     

     

     

    展开全文
  • 视频叠加区域,其中区域支持位图的加载、背景色更新等功能,简单理解就是可以设置透明度,也就是下面的Alpha值 (2)Cover遮挡 视频遮挡区域,其中区域支持纯色块遮挡,与Overlay叠加不同的是它不能加载图片,不能...

    (一)基本概念理解

    (1)Overlay叠加

        视频叠加区域,其中区域支持位图的加载、背景色更新等功能,简单理解就是可以设置透明度,也就是下面的Alpha值

    (2)Cover遮挡

        视频遮挡区域,其中区域支持纯色块遮挡,与Overlay叠加不同的是它不能加载图片,不能设置透明度

    (3)Alpha通道

     如果图形卡具有32位总线,附加的8位信号就被用来保存不可见的透明度信号以方便处理用,这就是Alpha通道。白色的alpha象素用以定义不透明的彩色象素,而黑色的alpha象素用以定义透明象素,黑白之间的灰阶用来定义半透明象素。

    •     VPSS OVERLAY时,Alpha取值范围为[0, 255]。取值越小,越透明。
    •     VPSS VENC 时,Alpha取值范围为[0, 127]。取值越小,越透明。

    (4)Stride图像跨距 

    Image Stride(内存图像行跨度) 当视频图像存储在内存时,图像的每一行末尾也许包含一些扩展的内容,这些扩展的内容只影响图像如何存储在内存中,但是不影响图像如何显示出来;Stride 就是这些扩展内容的名称,Stride 也被称作 Pitch,如果图像的每一行像素末尾拥有扩展内容,Stride 的值一定大于图像的宽度值,就像下图所示:


    两个缓冲区包含同样大小(宽度和高度)的视频帧,却不一定拥有同样的 Stride 值,如果你处理一个视频帧,你必须在计算的时候把 Stride 考虑进去;

    在做OSD水印的时候,叠加图片的stride值大于region画布的宽度时,该图像添加到画布会失败。

    (二)像素格式:

    • OVERLAY VENC类型支持:Argb1555,Argb4444
    • OVERLAY VPSS类型支持:Argb1555,Argb4444,Argb8888

    ARGB---Alpha,Red,Green,Blue.一种色彩模式,也就是RGB色彩模式附加上Alpha(透明度)通道,常见于32位位图的存储结构。

    (a)格式类型

    ALPHA_8:数字为8,图形参数应该由一个字节来表示,应该是一种8位的位图,常见的颜色格式:

    •     ARGB_4444:4+4+4+4=16,图形的参数应该由两个字节来表示,应该是一种16位的位图.
    •     ARGB_8888:8+8+8+8=32,图形的参数应该由四个字节来表示,应该是一种32位的位图.
    •     RGB_565:5+6+5=16,图形的参数应该由两个字节来表示,应该是一种16位的位图.

        Argb1555 也就是15位表示透明度和分别使用5位表示R,G,B,构成一个32位的位图,其中有两个位没有使用到。(b)颜色格式:
        颜色对照表可以查看:https://tool.oschina.net/commons?type=3
        同样是RGB颜色,但是颜色格式却有很多种,所以查表得到的颜色与显示的颜色是不能对应的,需要转换或是直接对应格式查找。

    (c)颜色转换

    三种RGB格式表示方式:

    • RGB555: R-5bit,G-5bit,B-5bit
    • RGB565: R-5bit,G-6bit,B-5bit
    • RGB888: R-8bit,G-8bit,B-8bit

    RGB888转RGB555
    RGB888 : R7 R6 R5 R4 R3 R2 R1 R0 G7 G6 G5 G4 G3 G2 G1 G0 B7 B6 B5 B4 B3 B2 B1 B0
    RGB555 :0 R7 R6 R5 R4 R3 G7 G6 G5 G4 G3 B7 B6 B5 B4 B3

    其它格式于此类似。

    (三)实时刷新OSD图像

        在海思官方提供的region sample中,它们使用的是现成的图片,也就是直接拿现成的图片加载到视频流中去,这样有一个问题,就是如果我需要实时改变OSD的内容,这个就不好处理了。 比如在视频中添加时间水印。

        以时间水印为例,要实现将时间水印添加到视频流流中去,大的流程只有两个:

    • 生成带带时间的图像
    • 将时间图像加载到预设置的region画布中去

    (1)生成时间位图:

       这里需要使用到freetype、SDL、SDl_ttf这三个库。

    • FreeType2是一个简单的跨平台的字体绘制引擎
    • SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。
    • SDL_ttf是TrueType字体渲染库,使用SDL库,几乎一样的便携。这取决于FreeType2处理TrueType字体数据。它允许程序员使用多个TrueType字体无需代码的字体渲染程序本身。随着轮廓字体和反走样的力量,高质量的文本输出可以毫不费力的获得。

        需要将这三个库移植到海思设备中去,交叉编译移植过程这里不介绍,网上有很多介绍。
        这里提供一个简单的测试程序:

    /************************************************************
    *Copyright (C),lcb0281at163.com lcb0281atgmail.com
    *BlogAddr: caibiao-lee.blog.csdn.net
    *FileName: debug_font_osd.c
    *Description:测试生成带时间字符的图像
    *Date:     2020-02-03
    *Author:   Caibiao Lee
    *Version:  V1.0
    *Others:
    *History:
    ***********************************************************/
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include "SDL/SDL.h"
    #include "SDL/SDL_ttf.h"
    
    #define FONT_PATH       "./font/hisi_osd.ttf"
    
    int string_to_bmp(char *pu8Str)
    {
        SDL_PixelFormat *fmt;
        TTF_Font *font;  
        SDL_Surface *text, *temp;  
    
        if (TTF_Init() < 0 ) 
        {  
            fprintf(stderr, "Couldn't initialize TTF: %s\n",SDL_GetError());  
            SDL_Quit();
        }  
    
        font = TTF_OpenFont(FONT_PATH, 80); 
        if ( font == NULL ) 
        {  
            fprintf(stderr, "Couldn't load %d pt font from %s: %s\n",18,"ptsize", SDL_GetError());  
        }  
    
        SDL_Color forecol = { 0xff, 0xff, 0xff, 0xff };  
        text = TTF_RenderUTF8_Solid(font, pu8Str, forecol);
    
        fmt = (SDL_PixelFormat*)malloc(sizeof(SDL_PixelFormat));
        memset(fmt,0,sizeof(SDL_PixelFormat));
        fmt->BitsPerPixel = 16;
        fmt->BytesPerPixel = 2;
        fmt->colorkey = 0xffffffff;
        fmt->alpha = 0xff;
    
        temp = SDL_ConvertSurface(text,fmt,0);
        SDL_SaveBMP(temp, "save.bmp"); 
    
        SDL_FreeSurface(text);  
        SDL_FreeSurface(temp);
        TTF_CloseFont(font);  
        TTF_Quit();  
    
        return 0;
    }

    工程中包含下面些内容:

    biao@ubuntu:~/test/github/hisi_sdk_develop/freetype_SDL_Dl_ttf_debug$ tree -L 2
    .
    ├── bin
    │   └── objs
    ├── debug_font_osd.c
    ├── debug_font_osd.h
    ├── font
    │   ├── hisi_osd.ttf
    │   └── hisi_osd.ttf_df
    ├── inc
    │   ├── freetype2
    │   ├── ft2build.h
    │   └── SDL
    ├── lib
    │   ├── libfreetype.a
    │   ├── libfreetype.so
    │   ├── libfreetype.so.6
    │   ├── libSDL-1.2.so.0
    │   ├── libSDL.a
    │   ├── libSDLmain.a
    │   ├── libSDL.so
    │   ├── libSDL_ttf-2.0.so.0
    │   ├── libSDL_ttf.a
    │   ├── libSDL_ttf.so
    │   └── pkgconfig
    ├── Makefile
    ├── save.bmp
    └── test
    
    8 directories, 18 files
    biao@ubuntu:~/test/github/hisi_sdk_develop/freetype_SDL_Dl_ttf_debug$ 

    生成保存的save.bmp图像如下:

    (2)将字符水印添加到视频流中:

        这里是根据官方sample修改而来,主要流程是:

    • 将解码器与编码器绑定,区域通道与编码通道绑定,从h264文件中读取数据流,输入到解码器中,由解码器中流向编码器,最后将编码器产生的数据存成文件。

        编码之后的图像带有区域图像的水印,这里可以根据实际的分辨率设置VENC和VDEC。

    /************************************************* 
    Function:    BIAO_RGN_AddOsdToVenc  
    Description: 将视频文件添加时间水印
    Input:  none
    OutPut: none
    Return: 0: success,none 0:error
    Others: 解码器输入的分辨率与编码器的输出分辨率可以不相同,
        比如将1080P图像解码后,可以再编码成720P图像。
    Author: Caibiao Lee
    Date:   2020-03-08
    *************************************************/
    HI_S32 BIAO_RGN_AddOsdToVenc(HI_VOID)
    {
        HI_S32 s32Ret = HI_SUCCESS;
        RGN_HANDLE OverlayHandle;
        HI_S32 u32OverlayRgnNum;
        MPP_CHN_S stSrcChn, stDesChn;
        RGN_ATTR_S stRgnAttrSet;
        RGN_CANVAS_INFO_S stCanvasInfo;
        BITMAP_S stBitmap;
        VENC_CHN VencChn;
        VDEC_CHN VdecChn;
        VDEC_SENDPARAM_S stVdesSendPram;
        VENC_PTHREAD_INFO_S stVencGetPram;
        SIZE_S stSize;
        FILE * pastream = NULL;
        HI_U32 i;
        int l_s32CanvasHandle = 0;
    
        /**分配缓存**/
        s32Ret = BIAO_RGN_SYS_Init(); 
        if(HI_SUCCESS != s32Ret)
        {
            printf("SAMPLE_RGN_SYS_Init failed! s32Ret: 0x%x.\n", s32Ret);
            goto END_O_VENC0;
        }
        
        /**创建区域,并将它添加到编码通道**/
        OverlayHandle    = 0;
        u32OverlayRgnNum = 1;
        s32Ret = BIAO_RGN_CreateOverlayForVenc(OverlayHandle, u32OverlayRgnNum);
        if(HI_SUCCESS != s32Ret)
        {
            printf("SAMPLE_RGN_CreateOverlayForVenc failed! s32Ret: 0x%x.\n", s32Ret);
            goto END_O_VENC1;
        }
        
        /**开启解码通道**/
        VdecChn = 0;
        s32Ret = BIAO_RGN_StartVdec(VdecChn);
        if(HI_SUCCESS != s32Ret)
        {
            printf("SAMPLE_RGN_StartVdec failed! s32Ret: 0x%x.\n", s32Ret);
            goto END_O_VENC2;
        }
        
        /**开启编码通道**/
        VencChn = 0;
        s32Ret = BIAO_RGN_StartVenc(VencChn);
        if(HI_SUCCESS != s32Ret)
        {
            printf("SAMPLE_RGN_StartVenc failed! s32Ret: 0x%x.\n", s32Ret);
            goto END_O_VENC3;
        }
        
        /**将解码通道绑定到编码通道**/
        stSrcChn.enModId  = HI_ID_VDEC;
        stSrcChn.s32DevId = 0;
        stSrcChn.s32ChnId = 0;
    
        stDesChn.enModId  = HI_ID_VENC;
        stDesChn.s32DevId = 0;
        stDesChn.s32ChnId = 0;
    
        s32Ret = HI_MPI_SYS_Bind(&stSrcChn, &stDesChn);
        if(HI_SUCCESS != s32Ret)
        {
            printf("HI_MPI_SYS_Bind failed! s32Ret: 0x%x.\n", s32Ret);
            goto END_O_VENC4;
        }
    
        /**创建一个线程用来从h264文件中读取数据,模拟h264数据流**/   
        stSize.u32Width  = DECODE_VIDEO_W;
        stSize.u32Height = DECODE_VIDEO_H;
        
        stVdesSendPram.bRun          = HI_TRUE;
        stVdesSendPram.VdChn         = VdecChn;
        stVdesSendPram.enPayload     = PT_H264;
        stVdesSendPram.enVideoMode   = VIDEO_MODE_FRAME;
        stVdesSendPram.s32MinBufSize = stSize.u32Height * stSize.u32Width / 2;
        pthread_create(&g_stVdecThread, NULL, BIAO_RGN_VdecSendStream, (HI_VOID*)&stVdesSendPram);
    
    
        /**更新OSD内容**/
        l_s32CanvasHandle = 0;
        pthread_create(&g_stRgnOsdThread, NULL, BIAO_UpdateCanvas, (HI_VOID*)&l_s32CanvasHandle);
    
    
        /**创建一个线程,将编码器输出的数据存成文件**/
        char pfilename[64]; 
        sprintf(pfilename, ENCODE_H264_FILE);
        pastream = fopen(pfilename, "wb");  
        HI_ASSERT( NULL != pastream);
    
        stVencGetPram.pstream   = pastream;
        stVencGetPram.VeChnId   = VencChn;
        stVencGetPram.s32FrmCnt = 0;
        pthread_create(&g_stVencThread, 0, BIAO_RGN_VencGetStream, (HI_VOID *)&stVencGetPram);
    
        printf("\n#############Sample start ok! Press Enter to switch!#############\n");
    
        
        /*************************************************
        step 8: stop thread and release all the resource
        *************************************************/
    
        /**延时之后推出编解码**/
        sleep(10);
        bExit = HI_TRUE;
        pthread_join(g_stVdecThread, 0);
    
        pthread_join(g_stVencThread, 0);
    
        pthread_join(g_stRgnOsdThread, 0);
        
        bExit = HI_FALSE;
        
    END_O_VENC4:
        HI_MPI_SYS_UnBind(&stSrcChn, &stDesChn);
    
    END_O_VENC3:
        BIAO_RGN_StopVenc(VencChn);
        
    END_O_VENC2:
        BIAO_RGN_StopVdec(VdecChn);
    
    END_O_VENC1:    
        BIAO_RGN_DestroyRegion(OverlayHandle, u32OverlayRgnNum);       
    
    END_O_VENC0:
        SAMPLE_COMM_SYS_Exit();
        
        return s32Ret;
    }

    将海思官方视频添加水印之后的视频效果如下:

    第一个生成时间图像的工程可以从下面获取:

    GitHub: freetype_SDL_Dl_ttf_debug 

    CSDN :  freetype_SDL_Dl_ttf_debug.tar.gz

    第二个将水印叠加到视频测工程可以从「目录与序言」提供的地址去获取

     

    本专栏第一篇文章「目录与序言」列出了专栏的完整目录,按目录顺序阅读,有助于你的理解。

     

     

     

    展开全文
  • 【一句话】区域售前管理工作思路

    千次阅读 2019-07-20 23:09:00
    如特定行业的持续深入研究(行业专家)、KA客户的粘性(客户经理)、复杂售前项目的沟通协调以及区域售前管理(售前管理/项目管理)。另外,也应充分考虑自己的工作经历,把原有的一些优势尽量利用起来。 7. 区域...

    Allman Brothers Band

    一句话的意思是:简单明了,让人能看懂。没有前戏,不故作深沉,也放弃高大上。

    1. 什么是售前

    • IT公司是卖产品、项目、技术服务的。在甲方爸爸买单之前,商务相关的工作由销售负责,技术的工作由售前负责。
    • 售前工作范围包括:前期了解商机、技术沟通、产品推荐、POC、招投标策划/投标/讲标等等。

    2. 产品售前与解决方案售前的的区别

    • 典型的售前,多位于产品或者偏向产品型的公司。系统集成型公司、项目外包型公司的售前工作,多由PM或公司/事业部中干完成。
    • 产品型公司,多产品型售前,售前多专精某一领域。产品及解决方案型公司,售前要求面更广更综合,除了产品技术方向,有时还要熟悉某行业,甚至跨行业。
    • 特别牛逼的产品公司,有时候售前的重要性大于销售。

    3. 售前管理与具体售前工作的区别

    • 具体售前工作:关注的是具体某售前项目的全生命周期支持。与具体销售配合。
    • 售前管理:关注的是区域/行业销售目标、对应的售前项目支持优先级定义、区域重点项目支持,甚至跨区域/行业支持等。与区域销售整体配合。

    4. 为什么会有区域售前

    • 对于业务、客户分散在全国各区域的公司来说,本地化区域化建设是非常重要的一个课题。因为涉及到售前响应速度、交付支持力度等。

    5. 区域售前工作与总部售前的各自特点

    • 理论上来说,总部售前的技术能力以及提升速度更快。因为离产品研发更近,天然具有优势。所以重大项目、高难度项目有时需要协调总部售前支持。
    • 区域售前更贴近客户。更容易了解本区域客户的行业地位、经营状况、组织架构及人员、产品/项目/技术具体的应用情况,能够长期跟踪KA客户,建立比较好的技术交流沟通氛围。

    6. 区域售前工作与总部售前职业发展的区别

    • 总部售前,更容易往产品经理、架构师等专精方向发展。因为离公司产品研发更近。
    • 区域售前,除产品经理、架构师外,可以考虑自身所处的地域及行业特点,建立自身优势。如特定行业的持续深入研究(行业专家)、KA客户的粘性(客户经理)、复杂售前项目的沟通协调以及区域售前管理(售前管理/项目管理)。另外,也应充分考虑自己的工作经历,把原有的一些优势尽量利用起来。

    7. 区域售前管理要点

    • 公司可销售产品及服务目录理解。先了解公司要卖啥。
    • 区域销售工作目标及工作安排理解。再了解区域上打算卖多少、谁来卖、怎么卖。
    • 区域售前团队规划配置。把对的人员准备好。根据公司产品特点以及区域销售目标调整优化团队人员配置。
    • 区域售前团队建设。售前套路总结、能力提升建设、销售售前和谐性建设、跨区域和谐性建设等。
    • 区域售前工作支持。根据销售目标,安排调整相对合适的售前支持,必要时跨区域协调。建立REVIEW和CHECK的机制。安排尽量结合个人的特点、能力、个性、家庭情况去安排工作。
    • 公司管理要求响应。响应并执行公司整体管理要求和售前体系的管理要求。

    转载于:https://my.oschina.net/allman90/blog/3076823

    展开全文
  • OSPF协议将其管理的网络划分为不同类型的若干区域(Area),其中标准区域特点是(64);存根区域(stub)的特点是(65)。 (64)A.不接受本地AS之外的路由信息,也不接受其他区域的路由汇总信息 B.不接受本地AS...

    OSPF协议将其管理的网络划分为不同类型的若干区域(Area),其中标准区域特点是(64);存根区域(stub)的特点是(65)。

    (64)A.不接受本地AS之外的路由信息,也不接受其他区域的路由汇总信息

    B.不接受本地AS之外的路由信息,对本地AS之外的目标采用默认路由

    C.可以接收任何链路更新信息和路由汇总信息

    D.可以学习其他AS的路由信息,对本地AS中的其他区域采用默认路由

    (65)A.不接受本地AS之外的路由信息,也不接受其他区域的路由汇总信息

    B.不接受本地AS之外的路由信息,对本地AS之外的目标采用默认路由

    C.可以接收任何链路更新信息和路由汇总信息

    D.可以学习其他AS的路由信息,对本地AS中的其他区域使用默认路由

    【答案】C B

    【解析】

    为了适应大型网络配置的需要,OSPF协议引入了“分层路由”的概念。如果网络规模很大,则路由器要学习的路由信息很多,对网络资源的消耗很大,所以典型的链路状态协议都把网络划分成较小的区域(Area),从而限制了路由信息传播的范围。每个区域就如同一个独立的网络,区域内的路由器只保存该区域的链路状态信息,使得路由器的链路状态数据库可以保持合理的大小,路由计算的时间和报文数量都不会太大。OSPF的区域分为以下5种,不同类型的区域对由自治系统外部传入的路由信息的处理方式不同:

    •标准区域:标准区域可以接收任何链路更新信息和路由汇总信息。

    •主千区域:主干区域是连接各个区域的传输网络,其他区域都通过主干区域交换路由信息。主干区域拥有标准区域的所有性质。

    •存根区域:不接受本地自治系统以外的路由信息,对自治系统以外的目标采用默认路由0.0.0.0。

    •完全存根区域:不接受自治系统以外的路由信息,也不接受自治系统内其他区域的路由汇总信息,发送到本地区域外的报文使用默认路由0.0.0.0。完全存根区域是Cisco定义的,是非标准的。

    •不完全存根区域(NSAA):类似于存根区域,但是允许接收以类型7的链路状态公告发送的外部路由信息。

    展开全文
  • Linux内核中每一个用户进程都可以访问4GB的线性虚空间,为了能表达真正被进程使用的虚拟内存空间,Linux定义了虚拟存储区域...进程的虚拟空间中可能有多个虚拟存储区域,Linux内核中对这些虚拟存储区域的组织方
  • Java内存管理:在前面的一些文章了解到javac编译的大体过程、Class文件结构、以及JVM字节码指令,下面我们详细了解Java内存区域:先说明JVM规范定义的JVM运行时分配的数据区有哪些,然后分别介绍它们的特点,并指出...
  • 日期 内核版本 架构 作者 GitHub CSDN 2016-08-31 ... Linux内存管理 1 前景回顾前面我们讲到服务器体系(SMP, NUMA, MPP)与共享存储器架构(UMA和NUMA)1.1 UMA和NUMA两种模型共享存储型多处理机有两种模型
  • 你的IT管理员已经限制对此应用一些区域的访问,你尝试访问的项目不可用。有关详细,请与你的IT支持人员联系。 按下win+s打开Cortana,在框中输入命令提示符,右键管理员身份运行 在命令提示符中输入 reg add “HKEY_...
  • DNS区域传输技术

    千次阅读 2018-12-18 10:22:08
    DNS区域传输技术 委托  例如,下图显示了 microsoft.com 域,该域包括 Microsoft 的域名。在单个服务器上首次创建 microsoft.com 域时,对于所有的 Microsoft DNS 名称空间,该域配置为单独区域。然而,如果这个 ...
  • 区域传输技术

    千次阅读 2015-09-13 23:23:37
    了解区域区域传输 域名系统 (DNS) 允许 DNS 名称空间分成几个区域,这些区域存储有关一个或多个 DNS 域的名称信息。对于包括在区域中的每个 DNS 域名,该区域成为该域的有关信息的权威性信息源。 了解...
  • 五度易链区域产业数字化管理平台 推荐专题:区域/园区产业数字化转型升级及管理 目前,我国区域产业正处于数字化转型的关键阶段,处于发展跨越提升最为有利的时期,能否做强区域产业链,从某种程度上来说,决定着...
  • 由于DNS服务已经随同Active Directory安装完成,我们可以直接通过选择【开始】-【管理工具】-【DNS】命令打开DNS管理器,对DNS服务进行配置与管理。 1. 创建正向查找区域 配置DNS服务,首先要创建DNS查找区域。所谓...
  • 二、管理正向区域 根据区域类型和区域存储方式的不同,管理DNS区域的方式也不同,在此我根据区域类型来进行介绍: 1、主要区域 活动目录集成主要区域和标准主要区域相比,常规选项不同,并且具有安全标签。 常规...
  • 解决Java初学者在使用布局管理器后不能调节各区域大小的问题
  • 2、创建辅助区域和存根区域 除了辅助区域数据不能和活动目录集成外,辅助区域和存根区域的创建步骤是一样的。活动目录集成存根区域和标准存根区域的区别如活动目录集成主要区域和标准主要区域,在此就不多叙述了...
  • 基于Java的房屋租赁管理系统,开放全部源代码,拿走即用,一个现成的毕业设计项目!
  • DNS区域分为两大类:正向查找区域和反向查找区域,其中 正向查找区域用于FQDN到IP地址的映射,当DNS客户端请求解析某个FQDN时,DNS服务器在正向查找区域中进行查找,并返回给DNS客户端对应的IP地址; ...
  • 基于JAVA SSM springboot实现的抗疫物质信息管理系统(源码+sql+论文《精品毕设》)主要功能:用户、区域、物质类型、物质详情、物质申请和审核以及我的申请和通知公告以及灵活控制菜单权限
  • SAP区域菜单管理

    千次阅读 2011-11-09 13:20:26
    在SAP系统的一大特色就是事务码起贯穿作用,大量的事务码如果不加以管理的话,寻找事务码就成了一件令人头疼的事情。好在SAP为我们提供了区域菜单的功能来组织大量的事务码。下面我就和大家一起来分享区域菜单的使用...
  • 文章目录1、题目2、数据说明3、要求4、步骤4.1创建一个6*6的格网,将商业圈道路数据随机分配到不同的志愿者进行管理。4.2对分配好的商业圈道路进行渲染,每种颜色表示一个志愿者,并导出为pdf格式。4.3将上述分析...
  • 华为 OSPF特殊区域

    千次阅读 多人点赞 2020-06-01 10:46:02
    (静 稳 忙 忍)!我个人理解为以下意思: 静:静的一半需要“争”;稳:稳的一半需要“急”,这里的急是指行动上;忙:忙的一半是不能急躁,做事要脚踏...一、概括 二、拓扑 三、配置与分析 四、总结 五、OSPF特殊区域
  • OSPF区域类型及详解

    千次阅读 2021-01-10 13:24:43
    所有的OSPF区域缺省情况下都是常规区域,当然, Area 0是常规区域中比较特殊的一个。 OSPF要求所有的非骨干区域(非0常规区域)都必须与Area 0直接相连。常规区域中允许Type-1, Type-2. Type-3, Type-4以及Type-5 LSA泛...
  • 分享6个国内优秀Java后台管理框架的开源项目

    万次阅读 多人点赞 2018-06-08 11:27:39
    分享6个国内优秀Java后台管理框架的开源项目,建议收藏!Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台...
  • JMV-内存管理-运行时数据区域

    千次阅读 2017-02-23 16:23:42
    JMV-内存管理-运行时数据区域 简介  Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。每个区域有各自的用途,创建时间以及销毁时间。有的区域随着虚拟机的进程启动而存在...
  • 企业网络安全区域划分的原则和方法 点击蓝字关注
  • ospf多区域的原理和配置实例

    千次阅读 2019-10-26 16:03:24
    一、前言 为什么ospf要划分多区域? (1)、防止环路(ospf同区域无环路的,多区域是会通过...2) 骨干区域:AREA0,其他区域必须连接到该区域,以交换路由信息。 让其他非骨干区域能够知道别的区域的网络情...
  • 布局管理

    千次阅读 2018-12-01 20:55:04
    绝对布局 绝对布局,顾名思义,就是硬性指定组件在容器中的位置和大小,可以使用绝对坐标的方式来指定组件的位置。...流布局管理器在整个容器中的布局正如其名,像“流”一样从左到右摆放组件,直到占据了这一行...
  • 你是公司的网络管理员。公司总部的网络分成了三个区域,包括内部区域(Trust)、外部区域(Untrust)和服务器区域(DMZ)。你设计通过防火墙来实现对数据的控制,确保公司内部网络安全,并通过DMZ区域对外网提供服务...
  • C#中的内存管理(二)存储区域划分

    千次阅读 2014-06-27 23:58:55
    栈区由系统自动管理释放,堆区由GC进行管理释放。 了解了数据的存储方式,我们继续了解C#中的数据类型。 C#中的所有数据类型都可以分为两类:值类型和引用类型。它们的区别来源于它们的复制方式:值类型的数据...
  • CODING 研发管理系统现已全面支持全类型代码仓库的 全球加速访问。 随着国内互联网红利的日趋枯竭与全球互联网的加速普及。越来越多的企业开始走出国门,将目光投向全世界,搭建跨国体系。跨出国门的中国企业在选择...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 637,319
精华内容 254,927
关键字:

区域管理