DAVINCI开发原理之三----达芬奇编解码引擎Codec Engine(CE)

DaVinci是DSP和ARM 双核架构的SOC芯片。对芯片与外界的交互通过ARM端的Montavista Linux和相关驱动与应用程序来管理, DSP端只处理编解码相关的算法。DSP和ARM之间的通讯和交互是通过引擎(Engine)和服务器(Server)来完成的。

1. 编解码引擎(Codec Engine)
a. 核心引擎API
    从应用来说,CE就是用来调用xDAIS算法的一组API的集合,用户可以通过这些API来实例化和调用xDAIS算法。达芬奇提供了一组VISA接口,用于给应用程序与xDM兼容的xDAIS算法相交互。需要注意,不管算法是运行在本地(ARM端),还是远端(DSP端),也不管硬件体系是只有ARM或是只有DSP或两者都有,也不管OS是Linux、VxWorks、DSP/BIOS,还是WinCE,对算法的接口调用都是一致的。这点通过引擎的配置文件*.cfg可以看出来,而且通过配置文件可以决定自己的codec是运行在ARM端还是DSP端。
    CE包括核心引擎APIVISA API核心引擎API相关接口模块为:初始化模块(CERuntime_)、CE运行时模块(Engine_)、抽象层内存模块(Memory_); VISA API的接口模块我们常用的有: 视频编码接口(VIDENCx_)、视频解码接口(VIDDECx_)、音频编码接口(AUDENCx_)、音频解码接口(AUDDECx_),各模块分别包含在对应的头文件中。
    应用程序必须使用CE的核心引擎的三个相关模块去打开和关闭编解码引擎的实例。 需要注意的是引擎的句柄是非线程保护的,对单独使用CE的每个线程来说,必须执行Engine_open并管理好自己的引擎句柄,而对多线程应用来说,也可以顺序的访问一个共享的引擎实例,我们目前采用的就是后者,只定义了一个引擎句柄,多个解码器共用。编解码引擎同时还提供相关的API用以访问系统的内存使用状况和CPU的负载信息,接口如下:
    >Engine_open:         打开一个编解码引擎;
    >Engine_close:        关闭一个编解码引擎,通常是在删除算法实例后调用之来释放相关资源;
    >Engine_getCpuLoad:   获取CPU的使用百分比;
    >Engine_getLastError: 获取最后一个失败操作所引发的错误代码;
    >Engine_getUsedMem:   获取内存使用状况
具体定义引擎所需要包含的头文件和如何定义和使用引擎可参考工程实例example_dsp1. 目前我们都是多个解码器共用一个引擎句柄,比如:
    static String engineName   = "videodec"; /*定义引擎名字,ceapp.cfg配置文件中会用到*/
    Engine_Handle ceHandle_264 = NULL; /*创建一个264解码器引擎句柄*/
    Engine_Error errorcode; /*用于返回引擎打开的状况信息,不同返回值代表的意义可参考相应头文件*/
    ceHandle_264 = Engine_open(engineName, NULL, &errorcode);

根据上述理解,我觉得如果多个线程需要单独使用自己的引擎时,应该可以定义多个引擎名字,创建多个引擎句柄,此时每个线程必须单独执行Engine_open(),并管理好自己的引擎句柄。

b. VISA API
    @创建一个算法实例: *_create()
编解码引擎ceHandle_264创建完毕后,可以通过它来创建自己的算法实例,需要调用*_create(),其中*可以是VIDEO或AUDIO的相应编解码模块的名字,例如:
    static String decoderName = "h264dec"; /*定义解码模块名字,用于标识算法名字,ceapp.cfg会用到*/
    VIDDEC_Handle 264Handle;               /*创建解码器句柄*/
    264Handle = VIDDEC_create(ceHandle_264, decoderName, NULL); /*在引擎上分配和初始化解码器,第三个参数可以用来初始化算法的相关参数,这些参数控制着算法的各种行为,参数结构依VISA中编码或解码器的不同而不同,具体结构内容可参考头文件*/

    @关闭一个算法实例: *_delete()
    VIDDEC_delete(264Handle); /*注意:只有当与算法相关的内存片清除后,才可以调用之删除算法实例*/

    @控制一个算法实例: *_control()
VIDDEC_control(264Handle, XDM_SETPARAME, dynamicParamsPtr, &encStatus);
    第一个参数是已经打开的算法实例句柄; 第二个参数是一整型的command id,它定义在xdm.h中; 第三个参数是需要动态改变算法的参数,比如在create中第三个参数已经为解码器初始化了一些参数,在这里可以对之做修改,但修改有条件,其具体结构内容可以参考头文件; 第四个参数是一个结构体变量,不同模块具有不同的结构,具体参考头文件。

    @通过算法实例处理数据: *_process()
    status = VIDDEC_process(264Handle &inBufDesc,&outBufDesc, &inArgs, &outArgs);
    第二和第三个参数是XDM_BufDesc类型的结构体,其中包含了内存片段的数目和开始地址以及长度信息;第四第五个参数分别为算法实例提供输入和输出地址。

    上述所有结构体都可以在: \opt\dvevm_#_#\xdais_#_#\packages\xdais\dm下面找到,并可以做修改。只是现在还不知道这些结构体具体怎么使用。


c. 编译"一个"编解码引擎----引擎配置文件(ceapp.cfg)
    引擎的配置文件是以*.cfg文件形式存储的,目前我们工程里面含两个*.cfg: app里面含ceapp.cfg,里面包含对引擎的配置,还有一个是video_copy.cfg,在server下,是对服务器的配置文件之一,后面会讲到。ceapp.cfg通过Makefile文件使用package.xdc来产生一个*.c文件和一个链接命令脚本文件。一个引擎配置文件包含如下内容: 引擎的名字以及包含在引擎内的编解码器和它们的名字。从这里可以看出,前面定义"h264dec"等名字的作用,用于应用程序中标识算法类别,也可以看出一个引擎是可以由几个编解码器模块共用的。我们以ceapp.cfg文件的内容为例说明配置参数的含义:

    /*--------------set up OSAL----------------*/
    var osalGlobal = xdc.useModule('ti.sdo.ce.osal.Global');
    osalGlobal.runtimeEnv = osalGlobal.DSPLINK_LINUX;
注:这两句是设置全局的模块使配置脚本生效,然后是设置引擎的运行环境,即需要用的DSP/BIOS Link和Linux OS).


    /*--------------get codec modules;i.e.implementation of codecs-------*/
var H264DEC = xdc.useModule('codecs.h264dec.H264DEC');
    注:设置需要用到的编解码器,即我们将要用到给定目录下的H264DEC。注意我们目前使用的都是codec目录下ti提供的videnc_copy,实际上我们可以修改的,另前面我们定义解码器的名字时用的小写的'h264dec',这里配置改成大写.

    /*---------------Engine Cofiguation---------------*/
    var Engine = xdc.useModule('ti.sdo.ce.Engine');
    var demoEngine = Engine.create("videodec", [
    {name: "h264dec", mod: H264DEC, local: false},
    /* {name: "h264enc", mod: H264ENC, local: false} ... 如果有的话*/
]);
    注:首先使ti.sdo.ce目录下的引擎可用,然后用create()创建一个引擎。每个引擎都有一个名字,这个名字会被开发人员用到(如打开引擎的时候,前面我们定义的引擎名字是"h264dec")。create()的参数是一关于算法描述的数组,每个算法描述包含下面几个字段:
    >name: 算法实例的名字,在标识算法时要用到,VIDEC_creat()等VISA API的参数,如前面定义264解码器名字"h264dec";
    >mod: 用来标识实际的算法实现模块,通常就是name的大写,如H264DEC.
    >local: 如果为真,算法实例在ARM端实现,否则通过codec server来创建DSP端的算法实例。

    demoEngine.server = "./encodeCombo.x64P";
    注:用于指明Codec Server.

-----------------------------------------------------------------------------------------------------------------------------------

两个cfg的比较:
    从ARM与DSP的通讯调用机制可看出,ARM端客户应用程序指令通过CE打包由OSAL层经DSPLINK发送到远端DSP服务器,在服务器端,先有server骨架经OSAL层解包获得指令及特定codec的申请,DSP codec处理完毕再经server打包经OSAL层由DSPLINK返回到本地ARM端CE,由此,两个cfg配置文件都需要设置OSAL及通讯环境DSPLINK,并申明好所使用到的各种编解码器,被申明的各编码器或各解码器(通常编码器s与解码器s分别放在两个文件夹下),两cfg文件中被声明的编码器或解码器路径是一致的,如: var VIDDEC_COPY = xdc.useModule('codecs.viddec_copy.VIDDEC_COPY');(.表示目录路径, viddec_copy目录下有个VIDDEC_COPY.xs文件)

-

-

-另一个人的介绍:

    编解码服务器(CS)就是一个二进制文件,它集成了编解码器,框架组件和一些系统代码,当CS运行在DSP上时,它使用了DSP/BIOS作为其内核。CS同时包括了对客户请求的相关DSP/BIOS线程。CS可以代表实际的DSP硬件、导入到DSP上的镜像文件以及正在运行的任务,其配置需要两个步骤:
  
>通过TCF脚本语言配置DSP/BIOS;
   >通过XDC配置剩下的组件,比如:FC组件、DSP/BIOS Link、Codec Engine等。
   配置完成的服务器镜像文件是在引擎配置文件(ceapp.cfg)中使用的,如前所述的demoEngine.server = "./encodeCombo.x64P";

a. 编译一个编解码服务器
       CS镜像文件的创建过程是通过前面介绍的XDC工具来完成的,所不同的是,CS在创建时需要一个main.c和相关的BIOS配置脚本.tcf文件.
>tcf: 脚本文件主要是对DSP/BIOS内核进行配置,如: 定义DSP的内存映射,设置DSP的中断向量表,创建和初始化其他DSP/BIOS数据对象等,具体可参见video_copy.tcf,注意我在里面添了一个关于trace的参数配置是原来没有的。

>main.c: 只要你的算法实现了XDM接口,就需要一个main.c的程序去初始化CE,然后用其他配置脚本来创建一个服务器镜像*.x64P. 在main.c里面除了调用CERuntime_init()初始化CE外,就是对于trace相关函数的初始化和处理,这部分暂时没有细究。另有一点值得注意,在这里可以实现对cache的重新配置,因为在tcf文件里面对cache的配置可能会不起作用,这是可以在这里以函数代码的方式来配,这点以前没有注意过。这里有点不明白的是,在ceapp_init()中已经做了一次CERuntime_init(),为何在CS处还要做一次?(我觉得是因为先编译CS,生成*.x64P,然后才编译app端,这样就可以理解成: 只要你的算法实现了XDM接口,就需要对CE做初始化CERuntime_init(),而CS的编译是调用了经XDM封装后的codec生成的*.a64P的)

>XDC相关文件:
>>>package.xdc
    /*--------------声明包名-----------------*/
    package server{}  
    (我们目前的.xdc是: package server.video.copy, 此即\server\video_copy\..xdc,应该无需改动)

>>>package.bld: 声明所必须包含的包,链接命令脚本,tcf文件和一些源文件,定义编译属性、平台和对象等。

>>>server.cfg: 这是CS配置的重点,说明如下。
/*第一部分: 声明运行环境和各种编解码模块, 与CE.cfg类似*/
/*--------------set up OSAL----------------*/
var osalGlobal = xdc.useModule('ti.sdo.ce.osal.Global');
osalGlobal.runtimeEnv = osalGlobal.DSPLINK_BIOS;
注:这两句是设置全局的模块使配置脚本生效,然后是设置引擎的运行环境,即需要用的DSP/BIOS Link,与CE.cfg有点区别).

/*---------------server Cofiguation---------------*/
var Server = xdc.useModule('tisdo.ce.Server');
Server.threadAttrs.stackSize = 16384;
Server.threadAttrs.priority = Server.MINPRI;

/*--------------get codec modules;i.e.implementation of codecs-------*/
var H264DEC = xdc.useModule('codecs.h264dec.H264DEC'); //与CE.cfg同,注意H264DEC标识的使用。

Server.algs = [
{name:"h264dec", mod:H264DEC,threadAttrs:{stackSize:4096,stackMemId:0,priority:Server.MINPRI+1} }, {...if have..},
   ];

/*第二部分: DSKT2 and DMAN3的配置:XDAIS算法内存和DMA的分配,参考配置文件*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/254199.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows操作系统安全加固

本文档旨在指导系统管理人员或安全检查人员进行Windows操作系统的安全合规性检查和配置。 1. 账户管理和认证授权 1.1 账户 默认账户安全 禁用Guest账户。禁用或删除其他无用账户(建议先禁用账户三个月,待确认没有问题后删除。)操作步骤 打开…

ios修改了coredata数据结构后,更新安装会闪退

如果iOS App 使用到CoreData,并且在上一个版本上有数据库更新(新增表、字段等操作),那在覆盖安装程序时就要进行CoreData数据库的迁移,具体操作如下: 1.选中你的mydata.xcdatamodeld文件,选择菜…

TI DAVINCI开发原理(总共5部分)

2011-06-03 11:14:17| 分类: TI 达芬奇视频处 | 标签: |字号大中小订阅 DAVINCI开发原理之一----ARM端开发环境的建立(DVEVM) 1. 对DAVINCI平台,TI在硬件上给予双核架构强有力的支撑,在DSP端用DSP/BIOS来支持音视频算法的运行…

数据库代码写法

1.创建数据库create database test2; 2.删除数据库drop database test2; 3.创建表 create table ceshi (ids int auto_increment primary key,uid varchar(20),name varchar(20),class varchar(20),foreign key (class) references class(code) ); create table class (code …

random库的使用

有关Python中random标准库的使用 Python中关于随机值的部分,借助的是根据当前的随机种子,通过梅森旋转算法,生成一段随机序列。 基本随机函数 random.seed(aNone)初始化给定的随机种子,默认值为当前的系统时间。 random.random()生…

ThinkPHP--栏目增删改查ADSF

<?php /*** 栏目发布*/ //V层&#xff0c;action/name值 action " :U( Admin/Cat/Cateadd )";/*** 添加栏目数据* C层&#xff0c;写相应的方法进行数据添加*/ public function add(){if(!IS_POST){$this->display();}else{//var_dump($_POST);$catModelD…

模拟查找晶元的位置

通过模板匹配找到所有模板位置&#xff0c;并且当单击某个模板时&#xff0c;选中某个模板 read_image (Image, C:/Users/22967/Desktop/晶圆找位置/0.bmp) dev_close_window () dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle) dev_display (Image)* draw_cir…

JavaScript常用函数之Eval()使用

eval() 功能&#xff1a;首先解释Javascript代码 然后执行它 用法&#xff1a;Eval&#xff08;codeString&#xff09; codeString是包含有javascript语句的字符串&#xff0c;在eval之后使用Javascript引擎编译。即&#xff1a;eval函数可以把一个字符串当作一个javascript表…

初探数位dp

前言&#xff1a;这是蒟蒻第一次写算法系列&#xff0c;请诸位大佬原谅文笔与排版。 一、导入 在刷题的时候&#xff0c;我们有时会见到这样一类问题&#xff1a;在区间$[l,r]$内&#xff0c;共有多少个整数满足某种条件。如果$l$和$r$间的差很小&#xff0c;我们可以考虑暴力枚…

Java演示手机发送短信验证码功能实现

我们这里采用阿里大于的短信API 第一步&#xff1a;登陆阿里大于&#xff0c;下载阿里大于的SDK a、在阿里大于上创建自己的应用 b、点击配置管理中的验证码&#xff0c;先添加签名&#xff0c;再配置短信模板 第二步&#xff1a;解压相关SDK&#xff0c;第一个为jar包&#xf…

使用标定板对相机位姿进行估计

使用标定板几个特定的点&#xff0c;来对相机相对标定板平面进行位姿估计。 首先进行相机的畸变校正&#xff0c;之后同个各个标定板间的圆点距离进行位姿估计。 gen_caltab (7, 7, 0.002, 0.5, C:/Users/22967/Desktop/新建文件夹/111.descr, C:/Users/22967/Desktop/新建文件…

音、视频文件格式

* 说明&#xff1a;首先要分清楚 媒体文件和编码的区别&#xff1a;文件是既包括视频又包括音频、甚至还带有脚本的一个集合&#xff0c;也可以叫容器&#xff1b;文件当中的视频和音频的压缩算法才是具体的编码。 *AVI音视频交互存储&#xff0c;最常见的音频视频容器。支持的…

ELK日志分析系统(转)

原创作品&#xff0c;允许转载&#xff0c;转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://467754239.blog.51cto.com/4878013/1700828大纲&#xff1a; 一、简介 二、Logstash 三、Redis 四、Elasticsearch 五、Kinaba 一、简介 …

Glide使用总结

首先&#xff0c;添加依赖 implementation com.github.bumptech.glide:glide:4.5.0 annotationProcessor com.github.bumptech.glide:compiler:4.5.0之后添加访问网络权限 <uses-permission android:name"android.permission.INTERNET" />一、常用的方法 1、加…

流行的音频编码标准

speech codec (G.711, G.723, G.726, G.729, iLBC) 各种各样的编解码在各种领域得到广泛的应用&#xff0c;下面就把各种codec的压缩率进行一下比较&#xff0c;不正确之处望各位同行指正。 Speech codec&#xff1a; 现主要有的speech codec 有: G.711, G.723, G.726 , G…

【angularjs】使用angular搭建项目,pc端实现网页中的内容不可复制

实现目标&#xff1a;不可复制页面内容 js:          <script language"javascript"> if (typeof(document.onselectstart) ! "undefined") { // IE下禁止元素被选取 document.onselectstart function (event){if(event.targe…

DIV+CSS如何让文字垂直居中?

在说到这个问题的时候&#xff0c;也许有人会问CSS中不是有vertical-align属性来设置垂直居中的吗&#xff1f;即使是某些浏览器不支持我只需做少许的CSS Hack技术就可以啊&#xff01;所以在这里我还要啰嗦两句&#xff0c;CSS中的确是有vertical-align属性&#xff0c;但是它…

Segments POJ 3304 直线与线段是否相交

题目大意&#xff1a;给出n条线段&#xff0c;问是否存在一条直线&#xff0c;使得n条线段在直线上的投影有至少一个公共点。 题目思路:如果假设成立&#xff0c;那么作该直线的垂线l&#xff0c;该垂线l与所有线段相交&#xff0c;且交点可为线段中的某两个交点 证明&#xff…

Linux Socket编程(不限Linux)

“一切皆Socket&#xff01;” 话虽些许夸张&#xff0c;但是事实也是&#xff0c;现在的网络编程几乎都是用的socket。 ——有感于实际编程和开源项目研究。 我们深谙信息交流的价值&#xff0c;那网络中进程之间如何通信&#xff0c;如我们每天打开浏览器浏览网页时&#xff…