×

签到

分享到微信

打开微信,使用扫一扫进入页面后,点击右上角菜单,

点击“发送给朋友”或“分享到朋友圈”完成分享

Cnstream自定义模块(一)实例分析---Osd、Encoder chong2020-08-14 11:43:29 回复 3 查看 CNStream 视频分析 视频流SDK
Cnstream自定义模块(一)实例分析---Osd、Encoder
分享到:



        在CnstreamOsd类与Encode类都继承于相同的基类Module,从下面的框架图中我们可以更清晰的看到三者的关系:



image.png


    从Module基类出发,我们来谈一下如何构建用户自己的功能模块:



image.png



    在该模块的类图中,我们可以看到很多的数据成员,和方法函数。但是其中大部分都是用户无关


的,也就是说对于用户而言,其中大部分都是为Module的友元类Pipeline提供工作的,由Pipeline


在模块运行时自动调用。用户无需关心内在的实现细节。


    而在用户设计过程中真正需要用户自己去设计实现的也就是四个方法,Open(),Close(),Process(),


CheckParamSet(),这四个方法中,前三个方法在Module中声明为纯虚函数,需要用户在自定义模块


的时候,进行重定义来完成相对应的功能。CheckParamSet()为虚函数,用户可以选择进行重定义,


CheckParamSet()是为模块参数在设置过程中的出现的异常提供了处理机制。在json文件中,必需


的参数没有设置,或者出现了不属于自身模块的参数设置。都会发出错误信息,提醒用户修改配置


参数。建议用户在自定义模块时重定义该方法。


    对于Open(),Close()两个方法而言,主要是为了模块在获取资源和析构资源时进行调用使用,一


般在Open()中通常对模块中的数据成员进行初始化操作。一般情况下Pipeline在初始化模块时,都


会通过配置模块参数的Json文件设置一 个paramSet 类型为<string,string>map,传递给Open()


函数,来对模块中的数据成员进行初始化。




image.png


    在上图的Osd实例中,我们可以看到在Open()方法中,对于标签文件的位置和绘制标签框的大小,


尺寸进行了初始化。而在Encoder模块实例中我们是初始化了输出文件的储存位置和文件储存类型。



image.png


    在Close()方法中,我们是去释放模块在运行中分配的资源, 一般是调用方法类所分配的内存资源。


    而Process模块就是在自定义模块时,封装模块所有功能的一个方法。接下来从具体实例出发来介


绍模块功能实现的方式。



image.png


image.png


    如上图所示,在EncoderOsd模块中,我们所具有相同名称的方法有Open(),Close(),Process(),


CheckParamSet()。其中Process()为模块功能实现的核心部分。在参考寒武纪Cnstream用户手册


我们可以发现,在Cnstrem的架构中,实现模块之间信息传递的功能类为CNFrameInfo。而在上图


中我们可以发现两个实例中Process()方法的参数类型都为指向CNFrameInfo的共享指针。

    

    由此也可了解Process是()为处理上游模块的数据,实现模块功能的方法。该方法需要用户自定义


实现,根据模块预先设定的功能进行编写实现。但是通常为了维护代码的易读性和简洁性。我们通


常会将实现功能的方法,单独封装在一个方法类中。在模块自身中设置一个类指针,用来在Process()


方法中调用该方法类的指针来实现模块功能。我们推荐用户使用这样的方法来增加模块代码的可读


性和方法类的可移植性。在上图所示的OsdEncoder类图中,我们可以发现GetEncoderContext()


GetOsdContext()两个方法,其返回值类型为shared_ptr,分别指向了EncoderContext


OsdContext两个方法类。即是我们所说的,设置方法类的类指针,在Process()中来调用这两个


方法,以实现模块功能。




    所以综上所述对于用户自定义模块而言,需要用户根据模块功能异化进行重定义的方法有Open(),


Close(),Process(),CheckParamSet(),其中Open(),Close()是用来管理模块资源,初始化模块数


成员CheckParamSet()用来检查模块参数是否设置准确。而Process(),则是模块功能实现的核心,


通常我们会另外定义一个方法类,在Process()中调用指向该类的指针,实现模块功能——当然你也


可以将模块功能实现代码一次性都封装在Process中,尽管我们不推荐使用这种方式。








版权所有 © 2024 寒武纪 Cambricon.com 备案/许可证号:京ICP备17003415号-1
关闭