OMAPL138学习----Codec Engine

Framework components 主要包括模块DSKT2和DMAN3,分别负责DSP侧的memory和EDMA资源管理。DSP算法使用的memory必须是先向DSKT2提出申请并由DSKT2分配得到的,同样DSP算法使用的EDMA通道也是向DMAN3申请并由DMAN3分配得到的。关于QDMA的操作,是通过ACPY3这个模块实现的,这样的好处是很容易对DSP侧不同的算法做整合,不同的算法之间不用担心资源(memory 和 EDMA)的冲突问题。 

目录结构:
  

examples
    +---apps
    |   `---system_files        Linux scripts describing which .ko's are required and how to load them for different platforms
    |       +---DM355
    |       +---DM357
    |       +---DM6446
    |       +---DM6467
    |       +---OMAP2530
    |       +---OMAP3530
    |       `---OMAPL137
    `---ti
        `---sdo
            `---ce
                `---examples    Buildable example codecs, DSP servers, and ARM and/or DSP apps
                    +---codecs
                    |   +---auddec1_copy
                    |   +---auddec1_ires
                    |   +---auddec_copy
                    |   +---audenc1_copy
                    |   +---audenc_copy
                    |   +---g711
                    |   +---imgdec1_copy
                    |   +---imgdec_copy
                    |   +---imgenc1_copy
                    |   +---imgenc_copy
                    |   +---scale
                    |   +---sphdec1_copy
                    |   +---sphdec_copy
                    |   +---sphenc1_copy
                    |   +---sphenc_copy
                    |   +---universalcopy
                    |   +---vidanalytics_copy
                    |   +---viddec1_copy
                    |   +---viddec2_copy
                    |   +---viddec2split_copy
                    |   +---viddec_copy
                    |   +---videnc1_copy
                    |   +---videnc_copy
                    |   `---vidtranscode_copy
                    |
                    +---extensions
                    |   `---scale
                    |
                    +---servers
                    |   `---all_codecs
                    |
                    `---apps
                        +---audio1_copy
                        |   +---async
                        |   `---sync
                        +---audio1_ires
                        +---audio_copy
                        +---image1_copy
                        +---image_copy
                        +---scale
                        +---server_api_example
                        +---server_trace
                        +---speech
                        +---speech1_copy
                        +---speech_copy
                        +---speech_copy_LAD
                        +---universal_copy
                        +---vidanalytics
                        +---video1_copy
                        +---video2_copy
                        +---video2split_copy
                        +---video_copy
                        `---vidtranscode

Running the video_copy example application on the DM644x and DM6467 DVEVMs

 
 

We assume you have your DVEVM properly set up, and that you are able to mount an NFS.

 
 

You must pass the MEM=120M (or less than 120M) parameter to your Linux kernel from your u-boot prompt, or you must have your Linux kernel configured to use no more than 120MB of physical memory. Read more in the following sections about the memory map.

 
 

Copy the necessary files into a directory visible from the DVEVM board (e.g. an NFS or hard drive mount, etc). Those files are:

 
 
  • dsplinkk.ko, the pre-configured, pre-built DSP Link driver.
  • cmemk.ko, a Contiguous Memory allocator that allows allocation of physically contiguous buffers of arbitrary sizes (even several MB) on the GPP.
  • loadmodules.sh and unloadmodules.sh, example scripts for loading any necessary kernel modules. Some platforms have different module dependencies than others, so the contents of these scripts may vary between platforms.
 
 

Build the examples as described below, and copy into the same directory as above the DSP server and GPP client executables (do it for simplicity; the executables do not need to be in the same directory where kernel modules are, but the executables themselves must sit in the same directory together). For example, to run the video_copy example, you need:

 
 
  • ti/sdo/ce/examples/servers/all_codecs/<platform>/all.x64P
  • ti/sdo/ce/examples/apps/video_copy/<platform>/app_remote.xv5T
 
 

Also copy the sample input video file to the same directory:

 
 
  • ti/sdo/ce/examples/apps/video_copy/<platform>/in.dat
 
 

Boot the EVM, change to the directory where you have copied all these files, and run
    sh ./loadmodules.sh

 
 

This script installs drivers necessary for your device (e.g. CMEM and Link) with appropriate information about the memory map.

 
 

You can find more information below about the default memory map. The CMEM module above is instructed to set aside two pools, one containing 20 4K buffers, the other containing two 1MB buffers. This is good enough for the video_copy application; your application will likely need different settings.

 
 

When you run the script, you should see the following output:

 
 
    $ ./loadmodules.sh
    cmem initialized 3 pools between 0x87800000 and 0x88000000
    dsplinkk: no version for "struct_module" found: kernel tainted.
    DSPLINK Module (1.61) created on Date: XXX XX XXXX Time: XX:XX:XX
 
 

Next, run the client application, which will automatically load the DSP server image:

 
 

    ./app.out

 
 

You will see several output lines:

 
 
    App-> Application started.
    CEapp-> Allocating contiguous buffer for 'input data' of size 1024...
    CEapp-> Contiguous buffer allocated OK (phys. addr=0x87fff000)
    CEapp-> Allocating contiguous buffer for 'encoded data' of size 1024...
    CEapp-> Contiguous buffer allocated OK (phys. addr=0x87ffe000)
    CEapp-> Allocating contiguous buffer for 'output data' of size 1024...
    CEapp-> Contiguous buffer allocated OK (phys. addr=0x87ffd000)
    App-> Processing frame 0...
    App-> Processing frame 1...
    App-> Processing frame 2...
    App-> Processing frame 3...
    App-> Processing frame 4...
    App-> Finished encoding and decoding 4 frames
    App-> Application finished successfully.
 
 

To verify that the application has executed correctly, verify the newly created out.dat file against the input in.dat file. They should be identical.

 
 
 
 

Building the examples: step-by-step instructions

 
 

1. [Optional] Copy the entire "examples" tree out of the product

 
 

This step is optional, but recommended if you plan to modify the samples in any way. It will ensure you have a backup copy of the original examples, as provided by the Codec Engine product.

 
 

Important: throughout the rest of this document, we will use the following notation:

 
 
  • <CE_EXAMPLES_INSTALL_DIR> - absolute path of the examples directory or the copy you made, e.g. /usr/work/examples
  • <CE_INSTALL_DIR> - root directory of your Codec Engine installation. The original examples are in <CE_INSTALL_DIR>/examples.
  • <BIOS_INSTALL_DIR> - root directory of your DSP/BIOS installation.
  • <XDC_INSTALL_DIR> - root directory of your xdctools installation.
  • directory/file - position of the file relative to the examples directory; for examples, ti/sdo/ce/examples/codecs/makefilerefers to <CE_EXAMPLES_INSTALL_DIR>ti/sdo/ce/examples/codecs/makefile.
 
 

2. Edit xdcpaths.mak to customize the build for your software installation and your hardware

 
 

At the root of the Examples directory is a build-related file named xdcpaths.mak that all Codec Engine example makefiles include. All users must edit this file to specify where various software components needed by Codec Engine are on their system, and often to narrow the list of hardware platforms to build for (thereby reducing the example build time and possibly the scope of external components).

 
 

The variables defined in xdcpaths.mak that most users must assign are: DEVICESGPPOSPROGRAMS, and various *_INSTALL_DIRvariables. Each are described more below as well as in comments throughout the xdcpaths.mak file.

 
 

Advanced users will note that these GNU make-based variables can be overridden on the command line. As a result, it is possible to tailor these makefiles without modifying them - by simply setting the variables on the command line when running "gmake".

 
 
2.1 xdcpaths.mak's DEVICES variable
 
 

The DEVICES variable indicates which hardware platforms should be built for. Most users are only interested in building for a single platform, and the other platforms can be removed from the DEVICES variable.

 
 

Note that there is a one-to-one mapping between the "short name" in the DEVICES macro and the "platform package" which is used. For example, the OMAP3530 value in DEVICES maps to the ti.platforms.evmOMAP3530 platform package.

 
 
2.2 xdcpaths.mak's GPPOS variable
 
 

The GPPOS variable indicates which GPP (General Purpose Processor, often an ARM) OS's should be built for. Most users are only interested in building for a single GPP OS (e.g. WinCE or Linux glibc or Linux uClibc), and the other GPP OS's can be removed from the GPPOS variable.

 
 

Note that there is a one-to-one mapping between the "short name" in the GPPOS macro and the "target module" which is used. For example, the WINCE value in GPPOS maps to the microsoft.targets.arm.WinCE target Module.

 
 
2.3 xdcpaths.mak's PROGRAMS variable
 
 

The PROGRAMS variable indicates roughly which system architecture the examples should be built for. Generally, Codec Engine supports "local" and "remote" codecs, and as a result there are 3 types of executables that can be built - APP_LOCALAPP_CLIENTand DSP_SERVER.

 
 

APP_LOCAL indicates that all examples that support the apps and codecs running on the same processor should be built. This is typically set for single core devices (e.g. DM365, DM6437), but can als be set for multi-core devices (e.g. OMAP3530, DM6446) where the app and codec run on either the GPP or the DSP.

 
 

APP_CLIENT and DSP_SERVER typically go together, and indicate that all examples that support remote execution of codecs should be built. If DSP_SERVER is set in the PROGRAMS variable and an appropriate multi-core platform is set in the DEVICES variable, the examples in examples/ti/sdo/ce/examples/servers may be built. APP_CLIENT indicates the "client" side of a "client/server" system, so GPP-side apps will be built (for the appropriate GPP OS's and hardware platforms set in GPPOS andDEVICES respectively).

 
 

Note that you can set all 3 (APP_LOCALAPP_CLIENT, and DSP_SERVER) or any subset of them. As a further example, if onlyDSP_SERVER is set, no applications will be built, but all components required to create a server (including codecs) will be built.

 
 
2.4 xdcpaths.mak's various *_INSTALL_DIR, CGTOOLS_* and CC_* variables
 
 

The xdcpaths.mak file also contains variables to indicate where products which Codec Engine may depend on are installed. The list of dependent products is a direct result of what values are assigned in the DEVICESGPPOS and PROGRAMS variables. For example, if you've set PROGRAMS to only APP_LOCALDEVICES to only DM355, and GPP_OS to LINUX_UCLIBC, you aren't required to provide DSPLINK_INSTALL_DIRBIOS_INSTALL_DIRCGTOOLS_V5T or CC_V5T

 
 

Further, if you're using a "full" installation of Codec Engine (see http://tiexpressdsp.com/index.php?title=Codec_Engine_FAQ#Why_do_some_distributions_have_a_cetools_directory_and_others_don.27t.3F for more details), many of the dependencies will be "auto-assigned" for you to the cetools/packages directory.

 
 

Please refer to the comments throughout xdcpaths.mak for more details.

 
 

Each directory contains a GNU makefile which enables you to build the sample in the current directory. Top-level directories also contain a makefile which steps into subdirectories and builds all the examples under the parent directory.

 
 

FYI, the xdcpaths.mak file is included by the individual makefiles for all the example codecs, servers, and applications.

 
 

Please keep in mind that MOST BUILD TROUBLES OCCUR WHEN ONE OF THE VARIOUS *_INSTALL_DIR VARIABLES ARE INCORRECT!Make sure there are no extra spaces (check the end of lines!), that every individual path (segment separated by the semicolon) is correct, character for character, and the build process is very likely to go smoothly.

 
 

3. Build example codecs

 
 

Change directory to ti/sdo/ce/examples/codecs and type

 
 

    gmake clean
    gmake

 
 

Alternatively, you can change into a specific codec's directory (e.g. ti/sdo/ce/examples/codecs/viddec_copy), and type

 
 

    gmake clean
    gmake

 
 

4. Build example extensions

 
 

Change directory to ti/sdo/ce/examples/extensions and type

 
 

    gmake clean
    gmake

 
 

Alternatively, you can change into a specific example extension directory (e.g. ti/sdo/ce/examples/extensions/scale), and type

 
 

    gmake clean
    gmake

 
 

5. Build example DSP servers

 
 

Note that this is only necessary for dual processor environments, like DM6446.

 
 

Change directory to ti/sdo/ce/examples/servers and type

 
 

    gmake clean
    gmake

 
 

Alternatively, you can change into a specific server's directory (e.g. ti/sdo/ce/examples/servers/video_copy), and type

 
 

    gmake clean
    gmake

 
 

Note: when developing your own codecs and applications, you will likely take one of the DSP server sample and modify it to suit your needs. These are the source files for this server application that you need to know about:

 
 
  • *.cfg: Configuration script that determines what codecs should be included in the server, and how some of the components (e.g. DSKT2 and DMAN3) will be configured.
  • *.tcf: TConf file for the app. It is often set to allow for a generous heap and static code and data. Be very careful with changing the memory map.
  • main.c: generic main()
  • link.cmd: application specific linker command file.
 
 

6. Build the GPP applications

 
 

Change directory to ti/sdo/ce/examples/apps (where the makefile is) and type

 
 

    gmake clean
    gmake

 
 

7. Copy files to the target and run

 
 

For a given application you want to run, you need to copy that application's executable to the target, and if your application requires a DSP server, you need to copy that DSP server to the target as well. (You can see which DSP server -- a DSP binary with .x64P or .x674 extension -- is required by the application if you look at the application's .cfg file.) In addition, you should copy the input data file "in.dat" to the target, keeping the relative position between the application executable and the in.dat file.

 
 

Also, you must make sure that all the required kernel modules (.ko's) for your target are loaded (tyically via the loadmodules.sh shell script.)

 
 

Example 1: Running the audio_copy example on evmDM6446:
Assuming you included DM6446 in DEVICESLINUX_GLIBC in GPPOS and APP_CLIENT in PROGRAMS, the ARM-side of the audio_copy example for evmDM6446 will be built into the examples/ti/sdo/ce/examples/apps/audio_copy/bin/ti_platforms_evmDM6446directory. Copy the app_remote.xv5T file to the target, along with in.dat -- which is in the same directory, so on the target both files should be in the same directory, as well. 

The remote.cfg file in that directory lists "all.x64P" as its DSP server image, so you must copy the all.x64P DSP executable for evmDM6446 from examples/ti/sdo/ce/examples/servers (more precisely fromexamples/ti/sdo/ce/examples/servers/all_codecs/bin/ti_platforms_evmDM6446/) to the target, in the same directory where the ARM-side executable is.

 
 

Example 2: Running the video1_copy example on evmDM355:
The evmDM355 only has the ARM, so we don't copy any DSP files on the target. From the build directoryti/sdo/ce/examples/apps/video1_copy/ we copy bin/ti_platforms_evmDM355/app_local.xv5T on the target, and the in.datfile as well, making sure in.dat is in the same directory on the target as the ARM executable.

 
 
 
 

Memory map

For information on the default DM6446 memory map -- as addressed by the kernel module loading scripts and DSP/BIOS configuration files (.tcf scripts) -- and instructions on how to change this map, please refer tohttp://tiexpressdsp.com/index.php?title=Changing_the_DVEVM_memory_map



The Core Engine APIs
Engine_open()
Engine_close()
Engine_getCpuLoad() 获取CPU使用百分比
Engine_getLastError()
Engine_getUseMem()
Engine_getNumAlgs()
Engine_getAlgInfo()


当创建GPP+DSP应用程序的时候,需要加载LINK和CMEM模块,在examples/apps/system_files/davinci/loadmodules.sh

1、打开Engine
  当你打开一个Engine时,要指定你想要打开的engine的名字,例如:

static String engineName = "auddec";
Engine_Handle ce;
Engine_Error errorcode;
ce = Engine_open(engineName, NULL, &errorcode);

注意:Engine句柄不是线程保护的,每个使用Engine的线程都要执行自己的Engine_open()函数。
Engine_open()允许你向Engine传递一个Engine_Attrs 结构体。这个结构体在Engine.h中定义。这个结构体允许你指定处理器ID来执行DSP Server。proclID的默认值是0。

typedef struct Engine_Attrs {
String procId;
} Engine_Attrs;

 

如果Engine_open()调用的Engine_Handle()返回为空,代表不能打开Engine。

Engine_Error

❏ Engine_EOK. Success.
❏ Engine_EEXIST. Name does not exist.
❏ Engine_ENOMEM. Can't allocate memory.
❏ Engine_EDSPLOAD. Can't load the DSP.
❏ Engine_ENOCOMM. Can't create a communication connection to
the DSP.
❏ Engine_ENOSERVER. Can't locate the Server on the DSP.
❏ Engine_ECOMALLOC. Can't allocate a communication buffer.

使用例子:

ce = Engine_open(engineName, NULL, &errorCode);
if (ce == NULL) {
printf("Error: could not open engine \"%s\";
Error code %d.\n", engineName, errorCode);
}

 

2、关闭一个Engine

调用Engine_close(ce);

只有当删除所有Engine创建的算法实例和释放缓冲区以及与算法相关的内存后,才可以使用这个函数。

 

3、获取关于算法配置的信息

  Engine_Error Engine_getNumAlgs(String name, Int *numAlgs)

参数name是Engine的名字,这个函数返回这些值:

❏ Engine_EOK. Success. In this case, *numAlgs returns the number of algorithms configured into the Engine.

❏ Engine_EEXIST. There is no Engine with the given name.

 
 

typedef struct Engine_AlgInfo {
Int algInfoSize; /* Size of this structure */
String name; /* Name of algorithm */
String *typeTab; /* inheritance hierarchy */
Bool isLocal; /* if TRUE, run locally */
} Engine_AlgInfo;

使用例子:

Int numAlgs, i;
Engine_AlgInfo algInfo;
Engine_Error err;
err = Engine_getNumAlgs("audio_copy", &numAlgs);
for (i = 0; i < numAlgs; i++) {
err = Engine_getAlgInfo(name, &algInfo, i);
printf("alg[%d]: name = %s typeTab = %s local = %d\n",
i, algInfo.name, *(algInfo.typeTab), algInfo.isLocal);
}

输出:

alg[0]: name = auddec_copy typeTab = ti.sdo.ce.audio.IAUDDEC local = 0
alg[1]: name = audenc_copy typeTab = ti.sdo.ce.audio.IAUDENC local = 0

 
 

The return values of Engine_getAlgInfo() are the following:
❏ Engine_EOK. Success.
❏ Engine_EEXIST. There is no Engine with the given name.
❏ Engine_EINVAL. The algInfoSize field of the Engine_AlgInfo object
passed to this function does not match the size of the Engine_AlgInfo
object in the Codec Engine library.
❏ Engine_ENOTFOUND. The index of the algorithm is out of range.


二、VISA 类
  MOD_create.
  MOD_process
  MOD_control
  MOD_delete

使用VISA接口,需要包含其头文件。例如,下面使用了音频解码API 模块,
  #include <ti/sdo/ce/audio/auddec.h>
1、创建一个算法实例
  使用*_create()
  例如:

Engine_Handle ce;
AUDDEC_Handle dec;
static String decoderName = "auddec_copy";
/* allocate and initialize audio decoder on the Engine */
dec = AUDDEC_create(ce, decoderName, NULL);


2)创建一个算法实例
 使用MOD_delete()  

/* tear down the codec and Engine */
AUDDEC_delete(dec)

只有释放缓冲区和算法相应的内存后,才可以使用这个函数。

3)管理一个算法实例
  使用*_control()
下例使用了AUDDEC_control()函数来
 1 #define NSAMPLES 1024
 2 #define IFRAMESIZE (NSAMPLES * sizeof(Int8)) /* raw (in) */
 3 #define OFRAMESIZE (NSAMPLES * sizeof(Int8)) /* decoded */
 4 static Char inBuf[IFRAMESIZE];
 5 static Char outBuf[OFRAMESIZE];
 6 XDM_BufDesc inBufDesc;
 7 XDM_BufDesc outBufDesc;
 8 XDAS_Int32 status;
 9 XDAS_Int32 bufSizes = NSAMPLES;
10 IAUDDEC_DynamicParams decDynParams;
11 IAUDDEC_Status decStatus;
12 /* prepare "global" buffer descriptor settings */
13 inBufDesc.numBufs = outBufDesc.numBufs = 1;
14 inBufDesc.bufSizes = outBufDesc.bufSizes = &bufSizes;
15 /* Query the decoder */
16 status = AUDDEC_control(dec, XDM_GETSTATUS, &decDynParams,
17 &decStatus);
18 if (status != AUDDEC_EOK) {
19 /* failure, report error and exit */
20 printf("decode control status = %ld\n", status);
21 return;
22 }
23 /* Validate decoder codec will meet buffer requirements */
24 if ((inBufDesc.numBufs > decStatus.bufInfo.maxNumInBufs) ||
25 (sizeof(inBuf) > decStatus.bufInfo.maxInBufSize[0]) ||
26 (outBufDesc.numBufs > decStatus.bufInfo.maxNumOutBufs) ||
27 (sizeof(outBuf) > decStatus.bufInfo.maxOutBufSize[0])) {
28 /* failure, report error and exit */
29 printf("Error: decoder codec feature conflict\n");
30 return;
31 }
 
 

AUDDEC_control()函数中的第一个参数 “dec”是AUDDEC_create()函数返回回来孤算法句柄。

第二个参数是命令ID ,有这些值:

  

❏ XDM_GETSTATUS. Queries the algorithm and fills a structure that contains status information about the capabilities of the algorithm.
❏ XDM_SETPARAMS. Sets the run-time dynamic parameters of the algorithm.
❏ XDM_GETPARAMS. Gets the current settings of the run-time dynamic parameters of the algorithm.
❏ XDM_RESET. Resets the algorithm. This may run an initializatio function or a special function to recover after an error or data loss.
❏ XDM_SETDEFAULT. Sets all parameters to their defaults.
❏ XDM_FLUSH. Handles end of stream conditions. Forces algorithm to output data without additional input. The recommended sequence is
to call the *_control() API with XDM_FLUSH and then make repeated calls to the *_process() API.
❏ XDM_GETBUFINFO. Queries the algorithm instance regarding the properties of its input and output buffers.

第三个参数是当你指定了XDM_SETPARAMS 或XDM_GETPARAMS 使用代码后的动态参数结构体的地址,
第四个参数是如果你指定了XDM_GETSTATUS命令码后的状态结构体地址。

4)使用算法实例来处理数据
  使用模块的*_process函数来运行算法。
如下例,使用了AUDDEC_process()函数从“in”中读取帧,解码这个音频,然后输出到“out”中。
 1 Int n;
 2 XDM_BufDesc inBufDesc;
 3 XDM_BufDesc outBufDesc;
 4 IAUDDEC_InArgs decInArgs;
 5 IAUDDEC_OutArgs decOutArgs;
 6 /* prepare "global" buffer descriptor settings */
 7 inBufDesc.numBufs = outBufDesc.numBufs = 1;
 8 inBufDesc.bufSizes = outBufDesc.bufSizes = &bufSizes;
 9 decInArgs.size = sizeof(decInArgs);
10 ...
11 /* Read complete frames from in, decode and write to out */
12 for (n = 0; fread(inBuf, sizeof (inBuf), 1, in) == 1; n++) {
13 XDAS_Int8 *src = inBuf;
14 XDAS_Int8 *dst = outBuf;
15 /* prepare "per loop" buffer descriptor settings */
16 inBufDesc.bufs = &src;
17 outBufDesc.bufs = &dst;
18 decInArgs.size = sizeof(decInArgs);
19 decInArgs.numBytes = sizeof(inBuf);
20 /* decode the frame */
21 status = AUDDEC_process(dec, &inBufDesc, &outBufDesc, 
22 &decInArgs, &decOutArgs);
23 if (status != AUDDEC_EOK) {
24 printf("frame %d: decode status = %ld\n", n, status);
25 }
26 /* write to file */
27 fwrite(dst, sizeof (outBuf), 1, out);
28 }
29 printf("%d frames decoded\n", n);
 
 

在这个AUDDEC_process()函数中,第一个参数“dec”是AUDDEC_create()函数返回的算法句柄。

第二个和第三个参数向音频解码器模块提供了XDM_BufDesc类型的缓冲地址。

typedef struct XDM_BufDesc {
XDAS_Int8 **bufs;
XDAS_Int32 numBufs;
XDAS_Int32 *bufSizes;
} XDM_BufDesc;

第四个和第五个参数向音频解码器提供了输入输出段地址。
5)重新定义远程算法优先级和内存请求

假定Server.MINPRI 是1。

Server.algs = [
{name: "audenc_copy", mod: AUDENC_COPY, threadAttrs: {
stackMemId: 0, priority: Server.MINPRI + 3}
},
...
];

方法:

Engine_Handle ce;
AUDENC_Handle enc;
AUDENC_Handle enc_high;
ce = Engine_open("audio_copy", NULL, NULL);
/* Create codec at the configured priority */
enc = AUDENC_create(ce, "audenc_copy", NULL);
/* Create second instance of codec, overriding the
* configured priority with a priority of 5 */
enc_high = AUDENC_create(ce, "audenc_copy:5", NULL) ;

重新定义一个算法的内存请求

在调整优先级时附加“:1”,传递给AUDENC_create()函数的名字有如下意义:

❏ "audenc_copy:5:1"
Create audenc_copy with priority 5 and with buffers allocated in
external memory.
❏ "audenc_copy::1"
Create audenc_copy with its configured priority and with buffers
allocated in external memory.

 

三、服务器接口

  在双核心CPU系统中,Englie被配置用来运行算法使用DSP SERVER

Engine_getServer()
Server_getNumMemSegs()
Server_getMemStat()
Server_radefineHeap()
Server_restoreHeap()

1)获取服务器句柄
  为了使用DSP Server,GPP 应用程序必须先通过调用Engine_getServer()函数开获取服务器句柄。
例如:

static String engineName = "auddec";
Engine_Handle engine;
Server_Handle server;
Engine_Error err;
engine = Engine_open(engineName, NULL, &err);
server = Engine_getServer(engine)

2)获取内存堆信息

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);

接口返回值

❏ Server_EOK - success. In this case, numSegs contains the number
of heaps in the DSP Server.
❏ Server_ERUNTIME - an internal runtime error occurred.

 
 

he memory statistics are returned in a
Server_MemStat structure:
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;

使用例子:
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);
}
 
 

3)重新配置DSP server的算法堆

Server_Status Server_redefineHeap(Server_Handle server,
String name, Uint32 base, Uint32 size);
Server_Status Server_restoreHeap(Server_Handle server,
String name);

返回值:

❏ Server_EOK. Success.
❏ Server_EINVAL. Changing to the new base address and size would
cause an overlap with another heap.
❏ Server_EINUSE. Memory is currently allocated in the algorithm
heap.
❏ Server_ENOTFOUND. No heap with the given name was found.
❏ Server_ERUNTIME. An internal runtime error occurred.
Server_restoreHeap() returns any of the following values:
❏ Server_EOK. Success.
❏ Server_EINVAL. Changing back to the original base address and
size would cause an overlap with another heap.
❏ Server_EINUSE. Memory is currently allocated in the algorithm
heap.
❏ Server_ENOTFOUND. No heap with the given name was found.

 

下例中GPP应用程序使用Memory_contigfAlloc()函数分配了连续的内存块,但是这个函数返回的地址的虚拟地址,所以在传递给Server_redefineHeap()之前必须转化为DSP地址。GPP函数Memory_getBufferPhysicalAddress()函数把虚拟地址转化为物理地址。

 1 Server_Handle server = NULL;
 2 Server_Status status;
 3 Engine_Handle ce = NULL;
 4 XDAS_Int8 *buf;
 5 Uint32 base;
 6 String decoderName = "auddec_copy";
 7 String encoderName = "audenc_copy";
 8 String engineName = "audio_copy";
 9 /* Open the Engine and get Server handle. Note, the
10 * Engine_open() call will load and start the DSP. */
11 ce = Engine_open(engineName, NULL, NULL);
12 server = Engine_getServer(ce);
13 /* Allocate block of memory, contiguous in physical memory */
14 buf = (XDAS_Int8 *)Memory_contigAlloc(BUFSIZE, ALIGNMENT);
15 /* Convert virtual address to physical address, which on 
16 * DM644x, happens to be the same as the DSP address. */ 
17 base = Memory_getBufferPhysicalAddress(buf, BUFSIZE, NULL);
18 /* Reconfigure the algorithm heap */
19 status = Server_redefineHeap(server, "DDRALGHEAP", base,
20 BUFSIZE);
21 'Create and run codecs'
22 'Delete codecs'
23 /* Reconfigure algorithm heap back to its original state. */
24 status = Server_restoreHeap(server, "DDRALGHEAP");
25 /* Free the buffer */
26 Memory_contigFree(buf, BUFSIZE);

 

4)缓冲处理和共享内存映射

控制接口使用XDM_BufDesc类型的输入输出缓冲指针,结构体如下:

typedef struct XDM_BufDesc {
XDAS_Int8 **bufs;
XDAS_Int32 numBufs;
XDAS_Int32 *bufSizes;
} XDM_BufDesc;



内存碎片:
对于双核CPU应用程序,传递给DSP的缓冲内存必须是连续的物理内存和高速缓存对齐。
算法缓冲区由Memory_module来管理,它使用了不同大小的缓冲池以保证内存不是离散的。
待续。。。。。。。
文档:
sprue67d - Codec Engine Application Developer User's Guide.pdf



转载于:https://www.cnblogs.com/zxycele/p/3636317.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值