[置顶] 使用 Codec Engine 的 API 函数(四)
来源:程序员人生 发布时间:2015-01-08 13:20:14 阅读次数:3587次
本文翻译自TI的手册,该手册是学习GPP+DSP开发的金典文档,希望对各位入门有所帮助,有理解不当的地方望请赐教。
Codec Engine Application Developer User's Guide.pdf (Literature Number: SPRUE67D)
《Codec Engine 利用开发使用手册》
http://blog.csdn.net/dyzok88/article/details/42154487
《第1章 Codec Engine 概要》 http://blog.csdn.net/dyzok88/article/details/42214813
《第2章 Codec Engine 安装和设置》 http://blog.csdn.net/dyzok88/article/details/42278109
《第3章 使用 Codec Engine 的示例利用程序》http://blog.csdn.net/dyzok88/article/details/42302793
// 正文
4.4 Codec 服务器 API 函数
在双 CPU 的系统中,被配置的引擎“远程”运行(在 DSP 中)算法,透明地使用1个“DSP服务器”。DSP 的服务器是1个集成算法及其框架的可履行程序(例如,DSP/BIOS,框架组件,编解码器,和 DSP Link 驱动程序),当引擎被打开时,这些组件将在 DSP 上被加载并开始运行。
服务器 API 函数能被在 GPP 上运行的利用程序调用,可以访问有关DSP的服务器的信息,并控制DSP服务器。更具体地说,这些 API 函数允许 GPP 利用程序获得有关 DSP 服务器中配置的内存堆数量,1个单独的内存堆确当前使用状态等信息。和重新配置 DSP 服务器的算法堆的基址和大小。
触及到服务器的 API 函数是:
1. Engine_getServer(). 取得服务器的句柄。
2. Server_getNumMemSegs(). 取得在1个服务器中的堆数。
3. Server_getMemStat(). 获得有关服务器的堆统计信息。
4. Server_redefineHeap(). 设置服务器堆的基址和大小。
5. Server_restoreHeap(). 重置服务器堆到默许基址和大小。
4.4.1 获得服务器句柄
要访问 DSP 服务器的引擎,GPP 利用程序必须通过调用 Engine_getServer() API 首先取得1个服务器句柄,例如:
static String engineName = "auddec";
Engine_Handle engine;
Server_Handle server;
Engine_Error err;
engine = Engine_open(engineName, NULL, &err);
server = Engine_getServer(engine);
注:引擎句柄,服务器句柄都不是线程保护。每一个线程使用服务器句柄必须履行自己的 Engine_getServer() 调用(使用自己的引擎句柄),或保证同享服务器句柄的同步访问的。
如果 Engine_getServer() 返回值是 NULL,那末引擎没有服务器。
4.4.2 获得内存堆信息
GPP 利用程序可以通过调用 Server_getNumMemSegs() 函数,取得配置到DSP服务器中内存堆的数量,例如:
Server_Handle server;
Server_Status status;
Int numSegs;
/* Get the server handle from a previously opened Engine */
server = Engine_getServer(engine);
status = Server_getNumMemSegs(server, &numSegs);
这些 API 函数返回以下毛病的代码:
1. Server_EOK - 成功。在这类情况下, numSegs 包括 DSP 服务器中的堆数。
2. Server_ERUNTIME - 产生内部运行时毛病。
1旦堆的数目是已知的,GPP 利用程序使用 Server_getMemStat() 函数,然后可以通过此数迭代,取得每一个堆统计信息。内存统计数据返回到 Server_MemStat 结构体:
typedef struct Server_MemStat {
Char name[Server_MAXSEGNAMELENTH+1];
/* Name of heap segment */
Uint32 base; /* Base address of heap */
Uint32 size; /* Original heap size */
Uint32 used; /* DSP MAUs of heap used */
Uint32 maxBlockLen; /* Length of largest free block */
} Server_MemStat;
下面的示例代码显示了这些 API 函数的用法(为了可读性,疏忽毛病检查)
Server_Handle server;
Int numSegs, i;
Server_MemStat stat;
Server_Status status;
status = Server_getNumMemSegs(server, &numSegs);
for (i = 0; i < numSegs; i++) {
status = Server_getMemStat(server, i, &stat);
printf("%s: base: 0x%x size: 0x%x used: 0x%x
max free block: 0x%x",
stat.name, stat.base, stat.size, stat.used,
stat.maxBlockLen);
}
Server_getMemStat() 的返回值以下:
1. Server_EOK. 成功。
2. Server_ENOTFOUND. 段号超越范围。
3. Server_ERUNTIME. 产生内部运行时毛病。
4.4.3 重新配置DSP服务器的算法堆
DSP 服务器可以被配置为专门用于算法堆的内存段。在某些情况下,DSP 服务器被配置小算法堆,GPP 利用程序在运行时,可能需要为算法堆提供较大的,被 DSP 服务器使用的连续内存块。然后,当堆不被 DSP 使用时,该内存可以从 DSP 回收,进而被 GPP 使用。下面的服务器 API 函数提供了重新配置 DSP 算法堆的手段:
Server_Status Server_redefineHeap(Server_Handle server,
String name, Uint32 base, Uint32 size);
Server_Status Server_restoreHeap(Server_Handle server,
String name);
传递给这些函数的参数" name "是要重新配置堆的名称;它必须不大于 Server_MAXSEGNAMELENGTH 字符长。传递给 Server_redefineHeap() 的" base "地址,必须为DSP的地址,从 base 到 base + size 的内存必须是连续的物理内存。参数" size "在 DSP MADUs(minimum addressable data units,可寻址的最小数据单元)中给出的。基址应为8字节对齐,但对大小没有对齐限制;大小的值为 0 是可接受的。
当堆上没有内存被当前分配时,在 DSP 算法堆只能被重新配置。 Server_restoreHeap() 函数重置算法堆的基地址和大小,回到它们的原始值(任何调用 Server_redefineHeap() 之前的值)。成功调用 Server_restoreHeap() 后,内存先前的“重新定义”到堆,可被该系统再次使用。
Server_redefineHeap() 的返回值以下:
1. Server_EOK. 成功。
2. Server_EINVAL. 改变到新的基地址和大小致使与另外一堆堆叠。
3. Server_EINUSE. 内存被当前分配在算法堆。
4. Server_ENOTFOUND. 没有发现给定的名称的堆。
5. Server_ERUNTIME. 产生内部运行时毛病。
Server_restoreHeap() 返回以下任何的值:
1. Server_EOK. 成功。
2. Server_EINVAL. 改变到新的基地址和大小致使与另外一堆堆叠。
3. Server_EINUSE. 内存被当前分配在算法堆。
4. Server_ENOTFOUND. 没有发现给定的名称的堆。
5. Server_ERUNTIME. 产生内部运行时毛病。
下面的代码说明,这两个 API 如何可以在 DM644x (1个 GPP+DSP 器件)上使用,在这个示例中,GPP 利用程序使用 Memory_contigAlloc() 函数分配1个连续的内存块。但是,通过此函数返回的地址是对 GPP 的虚拟地址,因此必须将其传递到 Server_redefineHeap() 前转换到 DSP 地址,Memory_getBufferPhysicalAddress() 函数可以将虚拟地址转换为 GPP 的物理地址,这样在 DM644x 的的情况下,就是相同的 DSP 的地址。
算法运行后,该算法堆被复位到其原来的大小和位置,为了更好的可读性,毛病检查被省略。
Server_Handle server = NULL;
Server_Status status;
Engine_Handle ce = NULL;
XDAS_Int8 *buf;
Uint32 base;
String decoderName = "auddec_copy";
String encoderName = "audenc_copy";
String engineName = "audio_copy";
/* Open the Engine and get Server handle. Note, the
* Engine_open() call will load and start the DSP. */
ce = Engine_open(engineName, NULL, NULL);
server = Engine_getServer(ce);
/* Allocate block of memory, contiguous in physical memory */
buf = (XDAS_Int8 *)Memory_contigAlloc(BUFSIZE, ALIGNMENT);
/* Convert virtual address to physical address, which on
* DM644x, happens to be the same as the DSP address. */
base = Memory_getBufferPhysicalAddress(buf, BUFSIZE, NULL);
/* Reconfigure the algorithm heap */
status = Server_redefineHeap(server, "DDRALGHEAP", base,
BUFSIZE);
'Create and run codecs'
'Delete codecs'
/* Reconfigure algorithm heap back to its original state. */
status = Server_restoreHeap(server, "DDRALGHEAP");
/* Free the buffer */
Memory_contigFree(buf, BUFSIZE);
在其他情况下,利用程序可能需要重新配置算法堆到1个地址,在 ARM 上分配缓冲区不能取得该地址。例如,假定在 DSP 上有固定的内存空间,该空间给利用程序用于算法堆之间的交替,取决运行甚么算法。在这类情况下,利用程序可以直接传递 DSP 的地址给 Server_redefineHeap() 函数。
生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠