BIOS: Initial commit of BIOS-only content 3.30.00.00_eng
authorChris Ring <cring@ti.com>
Tue, 19 Nov 2013 05:38:28 +0000 (21:38 -0800)
committerChris Ring <cring@ti.com>
Tue, 19 Nov 2013 05:38:28 +0000 (21:38 -0800)
This commit includes most/all of the CE sources required to
build BIOS-side libraries for [at least] local codecs.  The
sources are largely taken from the [TI-internal] ce-w08
(3.24.00.08) build.

390 files changed:
.gitignore [new file with mode: 0644]
ce-bios.bld [new file with mode: 0644]
ce-bios.mak [new file with mode: 0644]
packages/ti/sdo/ce/CERuntime.h [new file with mode: 0644]
packages/ti/sdo/ce/CERuntime.xdc [new file with mode: 0644]
packages/ti/sdo/ce/CERuntime.xdt [new file with mode: 0644]
packages/ti/sdo/ce/CERuntime.xs [new file with mode: 0644]
packages/ti/sdo/ce/Engine.c [new file with mode: 0644]
packages/ti/sdo/ce/Engine.h [new file with mode: 0644]
packages/ti/sdo/ce/Engine.xdc [new file with mode: 0644]
packages/ti/sdo/ce/Engine.xdt [new file with mode: 0644]
packages/ti/sdo/ce/Engine.xs [new file with mode: 0644]
packages/ti/sdo/ce/ICodec.xdc [new file with mode: 0644]
packages/ti/sdo/ce/ICodec.xs [new file with mode: 0644]
packages/ti/sdo/ce/Server.c [new file with mode: 0644]
packages/ti/sdo/ce/Server.h [new file with mode: 0644]
packages/ti/sdo/ce/Server.xdc [new file with mode: 0644]
packages/ti/sdo/ce/Server.xdt [new file with mode: 0644]
packages/ti/sdo/ce/Server.xs [new file with mode: 0644]
packages/ti/sdo/ce/ServerDataSheet.html.xdt [new file with mode: 0644]
packages/ti/sdo/ce/ServerDefs.h [new file with mode: 0644]
packages/ti/sdo/ce/Settings.xdc [new file with mode: 0644]
packages/ti/sdo/ce/Settings.xdt [new file with mode: 0644]
packages/ti/sdo/ce/VISA.xdc [new file with mode: 0644]
packages/ti/sdo/ce/_Engine.h [new file with mode: 0644]
packages/ti/sdo/ce/_Server.h [new file with mode: 0644]
packages/ti/sdo/ce/alg/Algorithm.h [new file with mode: 0644]
packages/ti/sdo/ce/alg/Algorithm.xdc [new file with mode: 0644]
packages/ti/sdo/ce/alg/Algorithm.xdt [new file with mode: 0644]
packages/ti/sdo/ce/alg/Algorithm_BIOS.c [new file with mode: 0644]
packages/ti/sdo/ce/alg/Algorithm_noOS.c [new file with mode: 0644]
packages/ti/sdo/ce/alg/_Algorithm.h [new file with mode: 0644]
packages/ti/sdo/ce/alg/_alg.h [new file with mode: 0644]
packages/ti/sdo/ce/alg/alg.h [new file with mode: 0644]
packages/ti/sdo/ce/alg/alg_control.c [new file with mode: 0644]
packages/ti/sdo/ce/alg/alg_create.c [new file with mode: 0644]
packages/ti/sdo/ce/alg/alg_malloc.c [new file with mode: 0644]
packages/ti/sdo/ce/alg/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/alg/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/alg/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/async-extensions.txt [new file with mode: 0644]
packages/ti/sdo/ce/audio/IAUDDEC.xdc [new file with mode: 0644]
packages/ti/sdo/ce/audio/IAUDENC.xdc [new file with mode: 0644]
packages/ti/sdo/ce/audio/_auddec.h [new file with mode: 0644]
packages/ti/sdo/ce/audio/_audenc.h [new file with mode: 0644]
packages/ti/sdo/ce/audio/auddec.c [new file with mode: 0644]
packages/ti/sdo/ce/audio/auddec.h [new file with mode: 0644]
packages/ti/sdo/ce/audio/auddec_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/audio/auddec_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/audio/audenc.c [new file with mode: 0644]
packages/ti/sdo/ce/audio/audenc.h [new file with mode: 0644]
packages/ti/sdo/ce/audio/audenc_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/audio/audenc_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/audio/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/audio/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/audio/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/audio1/IAUDDEC1.xdc [new file with mode: 0644]
packages/ti/sdo/ce/audio1/IAUDENC1.xdc [new file with mode: 0644]
packages/ti/sdo/ce/audio1/_auddec1.h [new file with mode: 0644]
packages/ti/sdo/ce/audio1/_audenc1.h [new file with mode: 0644]
packages/ti/sdo/ce/audio1/auddec1.c [new file with mode: 0644]
packages/ti/sdo/ce/audio1/auddec1.h [new file with mode: 0644]
packages/ti/sdo/ce/audio1/auddec1_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/audio1/auddec1_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/audio1/audenc1.c [new file with mode: 0644]
packages/ti/sdo/ce/audio1/audenc1.h [new file with mode: 0644]
packages/ti/sdo/ce/audio1/audenc1_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/audio1/audenc1_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/audio1/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/audio1/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/audio1/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/global/CESettings.c [new file with mode: 0644]
packages/ti/sdo/ce/global/CESettings.h [new file with mode: 0644]
packages/ti/sdo/ce/global/Settings.xdc [new file with mode: 0644]
packages/ti/sdo/ce/global/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/global/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/global/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/image/IIMGDEC.xdc [new file with mode: 0644]
packages/ti/sdo/ce/image/IIMGDEC_dsutils.xs [new file with mode: 0644]
packages/ti/sdo/ce/image/IIMGENC.xdc [new file with mode: 0644]
packages/ti/sdo/ce/image/IIMGENC_dsutils.xs [new file with mode: 0644]
packages/ti/sdo/ce/image/IMGDECConfig.xdc [new file with mode: 0644]
packages/ti/sdo/ce/image/IMGDECConfig.xdt [new file with mode: 0644]
packages/ti/sdo/ce/image/IMGENCConfig.xdc [new file with mode: 0644]
packages/ti/sdo/ce/image/IMGENCConfig.xdt [new file with mode: 0644]
packages/ti/sdo/ce/image/_imgdec.h [new file with mode: 0644]
packages/ti/sdo/ce/image/_imgenc.h [new file with mode: 0644]
packages/ti/sdo/ce/image/imgdec.c [new file with mode: 0644]
packages/ti/sdo/ce/image/imgdec.h [new file with mode: 0644]
packages/ti/sdo/ce/image/imgdec_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/image/imgdec_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/image/imgenc.c [new file with mode: 0644]
packages/ti/sdo/ce/image/imgenc.h [new file with mode: 0644]
packages/ti/sdo/ce/image/imgenc_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/image/imgenc_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/image/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/image/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/image/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/image1/IIMGDEC1.xdc [new file with mode: 0644]
packages/ti/sdo/ce/image1/IIMGDEC1_dsutils.xs [new file with mode: 0644]
packages/ti/sdo/ce/image1/IIMGENC1.xdc [new file with mode: 0644]
packages/ti/sdo/ce/image1/IIMGENC1_dsutils.xs [new file with mode: 0644]
packages/ti/sdo/ce/image1/IMGDEC1Config.xdc [new file with mode: 0644]
packages/ti/sdo/ce/image1/IMGDEC1Config.xdt [new file with mode: 0644]
packages/ti/sdo/ce/image1/IMGENC1Config.xdc [new file with mode: 0644]
packages/ti/sdo/ce/image1/IMGENC1Config.xdt [new file with mode: 0644]
packages/ti/sdo/ce/image1/_imgdec1.h [new file with mode: 0644]
packages/ti/sdo/ce/image1/_imgenc1.h [new file with mode: 0644]
packages/ti/sdo/ce/image1/imgdec1.c [new file with mode: 0644]
packages/ti/sdo/ce/image1/imgdec1.h [new file with mode: 0644]
packages/ti/sdo/ce/image1/imgdec1_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/image1/imgdec1_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/image1/imgenc1.c [new file with mode: 0644]
packages/ti/sdo/ce/image1/imgenc1.h [new file with mode: 0644]
packages/ti/sdo/ce/image1/imgenc1_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/image1/imgenc1_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/image1/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/image1/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/image1/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/ipc/Comm.h [new file with mode: 0644]
packages/ti/sdo/ce/ipc/IIpc.xdc [new file with mode: 0644]
packages/ti/sdo/ce/ipc/Processor.h [new file with mode: 0644]
packages/ti/sdo/ce/ipc/Settings.xdc [new file with mode: 0644]
packages/ti/sdo/ce/ipc/bios/Comm_BIOS.c [new file with mode: 0644]
packages/ti/sdo/ce/ipc/bios/Ipc.xdc [new file with mode: 0644]
packages/ti/sdo/ce/ipc/bios/Ipc.xdt [new file with mode: 0644]
packages/ti/sdo/ce/ipc/bios/Ipc.xs [new file with mode: 0644]
packages/ti/sdo/ce/ipc/bios/Ipc_defs.c [new file with mode: 0644]
packages/ti/sdo/ce/ipc/bios/Processor.xdc [new file with mode: 0644]
packages/ti/sdo/ce/ipc/bios/Processor.xdt [new file with mode: 0644]
packages/ti/sdo/ce/ipc/bios/Processor.xs [new file with mode: 0644]
packages/ti/sdo/ce/ipc/bios/Processor_noOS.c [new file with mode: 0644]
packages/ti/sdo/ce/ipc/bios/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/ipc/bios/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/ipc/bios/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/ipc/dsplink/Comm_dsplink.c [new file with mode: 0644]
packages/ti/sdo/ce/ipc/dsplink/Ipc.xdc [new file with mode: 0644]
packages/ti/sdo/ce/ipc/dsplink/Ipc.xdt [new file with mode: 0644]
packages/ti/sdo/ce/ipc/dsplink/Processor.xdc [new file with mode: 0644]
packages/ti/sdo/ce/ipc/dsplink/Processor.xdt [new file with mode: 0644]
packages/ti/sdo/ce/ipc/dsplink/Processor.xs [new file with mode: 0644]
packages/ti/sdo/ce/ipc/dsplink/Processor_dsplink.c [new file with mode: 0644]
packages/ti/sdo/ce/ipc/dsplink/dsp/Settings.xdc [new file with mode: 0644]
packages/ti/sdo/ce/ipc/dsplink/dsp/Settings.xdt [new file with mode: 0644]
packages/ti/sdo/ce/ipc/dsplink/dsp/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/ipc/dsplink/dsp/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/ipc/dsplink/dsp/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/ipc/dsplink/makefile [new file with mode: 0644]
packages/ti/sdo/ce/ipc/dsplink/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/ipc/dsplink/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/ipc/dsplink/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/ipc/linux/Comm_posix.c [new file with mode: 0644]
packages/ti/sdo/ce/ipc/linux/Ipc.xdc [new file with mode: 0644]
packages/ti/sdo/ce/ipc/linux/Ipc.xdt [new file with mode: 0644]
packages/ti/sdo/ce/ipc/linux/Processor_posix.c [new file with mode: 0644]
packages/ti/sdo/ce/ipc/linux/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/ipc/linux/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/ipc/linux/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/ipc/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/ipc/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/ipc/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/node/NODE.xdc [new file with mode: 0644]
packages/ti/sdo/ce/node/NODE.xdt [new file with mode: 0644]
packages/ti/sdo/ce/node/_node.h [new file with mode: 0644]
packages/ti/sdo/ce/node/node.h [new file with mode: 0644]
packages/ti/sdo/ce/node/node_crea.c [new file with mode: 0644]
packages/ti/sdo/ce/node/node_dele.c [new file with mode: 0644]
packages/ti/sdo/ce/node/node_exec.c [new file with mode: 0644]
packages/ti/sdo/ce/node/node_getpri.c [new file with mode: 0644]
packages/ti/sdo/ce/node/node_init.c [new file with mode: 0644]
packages/ti/sdo/ce/node/node_start.c [new file with mode: 0644]
packages/ti/sdo/ce/node/node_stat.c [new file with mode: 0644]
packages/ti/sdo/ce/node/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/node/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/node/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/osal/File.h [new file with mode: 0644]
packages/ti/sdo/ce/osal/Global.h [new file with mode: 0644]
packages/ti/sdo/ce/osal/Global.xdc [new file with mode: 0644]
packages/ti/sdo/ce/osal/Global.xdt [new file with mode: 0644]
packages/ti/sdo/ce/osal/Global.xs [new file with mode: 0644]
packages/ti/sdo/ce/osal/IOsal.xdc [new file with mode: 0644]
packages/ti/sdo/ce/osal/Loader.h [new file with mode: 0644]
packages/ti/sdo/ce/osal/Lock.h [new file with mode: 0644]
packages/ti/sdo/ce/osal/LockMP.h [new file with mode: 0644]
packages/ti/sdo/ce/osal/Log.h [new file with mode: 0644]
packages/ti/sdo/ce/osal/Memory.h [new file with mode: 0644]
packages/ti/sdo/ce/osal/Queue.c [new file with mode: 0644]
packages/ti/sdo/ce/osal/Queue.h [new file with mode: 0644]
packages/ti/sdo/ce/osal/Sem.h [new file with mode: 0644]
packages/ti/sdo/ce/osal/SemMP.h [new file with mode: 0644]
packages/ti/sdo/ce/osal/Trace.h [new file with mode: 0644]
packages/ti/sdo/ce/osal/bios/File_BIOS.c [new file with mode: 0644]
packages/ti/sdo/ce/osal/bios/Global.xs [new file with mode: 0644]
packages/ti/sdo/ce/osal/bios/Global_BIOS.c [new file with mode: 0644]
packages/ti/sdo/ce/osal/bios/Global_BIOS.h [new file with mode: 0644]
packages/ti/sdo/ce/osal/bios/Loader_noOS.c [new file with mode: 0644]
packages/ti/sdo/ce/osal/bios/Memory_BIOS.c [new file with mode: 0644]
packages/ti/sdo/ce/osal/bios/Settings.xdc [new file with mode: 0644]
packages/ti/sdo/ce/osal/bios/Settings.xdt [new file with mode: 0644]
packages/ti/sdo/ce/osal/bios/Trace_SysCBuf.c [new file with mode: 0644]
packages/ti/sdo/ce/osal/bios/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/osal/bios/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/osal/bios/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/osal/linux/File_posix.c [new file with mode: 0644]
packages/ti/sdo/ce/osal/linux/Global_noOS.c [new file with mode: 0644]
packages/ti/sdo/ce/osal/linux/Loader_linux.c [new file with mode: 0644]
packages/ti/sdo/ce/osal/linux/LockMP_posix.c [new file with mode: 0644]
packages/ti/sdo/ce/osal/linux/Lock_posix.c [new file with mode: 0644]
packages/ti/sdo/ce/osal/linux/Memory_cmem.c [new file with mode: 0644]
packages/ti/sdo/ce/osal/linux/Memory_noOS.c [new file with mode: 0644]
packages/ti/sdo/ce/osal/linux/SemMP_posix.c [new file with mode: 0644]
packages/ti/sdo/ce/osal/linux/Sem_posix.c [new file with mode: 0644]
packages/ti/sdo/ce/osal/linux/Settings.xdc [new file with mode: 0644]
packages/ti/sdo/ce/osal/linux/Settings.xdt [new file with mode: 0644]
packages/ti/sdo/ce/osal/linux/Trace.c [new file with mode: 0644]
packages/ti/sdo/ce/osal/linux/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/osal/linux/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/osal/linux/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/osal/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/osal/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/osal/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/rms.c [new file with mode: 0644]
packages/ti/sdo/ce/rms.h [new file with mode: 0644]
packages/ti/sdo/ce/skel.h [new file with mode: 0644]
packages/ti/sdo/ce/speech/ISPHDEC.xdc [new file with mode: 0644]
packages/ti/sdo/ce/speech/ISPHENC.xdc [new file with mode: 0644]
packages/ti/sdo/ce/speech/_sphdec.h [new file with mode: 0644]
packages/ti/sdo/ce/speech/_sphenc.h [new file with mode: 0644]
packages/ti/sdo/ce/speech/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/speech/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/speech/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/speech/sphdec.c [new file with mode: 0644]
packages/ti/sdo/ce/speech/sphdec.h [new file with mode: 0644]
packages/ti/sdo/ce/speech/sphdec_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/speech/sphdec_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/speech/sphenc.c [new file with mode: 0644]
packages/ti/sdo/ce/speech/sphenc.h [new file with mode: 0644]
packages/ti/sdo/ce/speech/sphenc_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/speech/sphenc_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/speech1/ISPHDEC1.xdc [new file with mode: 0644]
packages/ti/sdo/ce/speech1/ISPHENC1.xdc [new file with mode: 0644]
packages/ti/sdo/ce/speech1/_sphdec1.h [new file with mode: 0644]
packages/ti/sdo/ce/speech1/_sphenc1.h [new file with mode: 0644]
packages/ti/sdo/ce/speech1/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/speech1/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/speech1/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/speech1/sphdec1.c [new file with mode: 0644]
packages/ti/sdo/ce/speech1/sphdec1.h [new file with mode: 0644]
packages/ti/sdo/ce/speech1/sphdec1_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/speech1/sphdec1_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/speech1/sphenc1.c [new file with mode: 0644]
packages/ti/sdo/ce/speech1/sphenc1.h [new file with mode: 0644]
packages/ti/sdo/ce/speech1/sphenc1_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/speech1/sphenc1_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/universal/IUNIVERSAL.xdc [new file with mode: 0644]
packages/ti/sdo/ce/universal/UNIVERSALConfig.xdc [new file with mode: 0644]
packages/ti/sdo/ce/universal/UNIVERSALConfig.xdt [new file with mode: 0644]
packages/ti/sdo/ce/universal/_universal.h [new file with mode: 0644]
packages/ti/sdo/ce/universal/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/universal/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/universal/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/universal/universal.c [new file with mode: 0644]
packages/ti/sdo/ce/universal/universal.h [new file with mode: 0644]
packages/ti/sdo/ce/universal/universal_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/universal/universal_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/utils/syscbuf/SysCBuf.c [new file with mode: 0644]
packages/ti/sdo/ce/utils/syscbuf/SysCBuf.xdc [new file with mode: 0644]
packages/ti/sdo/ce/utils/syscbuf/SysCBuf.xdt [new file with mode: 0644]
packages/ti/sdo/ce/utils/syscbuf/SysCBuf.xs [new file with mode: 0644]
packages/ti/sdo/ce/utils/syscbuf/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/utils/syscbuf/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/utils/syscbuf/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/utils/xdm/XdmUtils.c [new file with mode: 0644]
packages/ti/sdo/ce/utils/xdm/XdmUtils.h [new file with mode: 0644]
packages/ti/sdo/ce/utils/xdm/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/utils/xdm/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/utils/xdm/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/vidanalytics/IVIDANALYTICS.xdc [new file with mode: 0644]
packages/ti/sdo/ce/vidanalytics/_vidanalytics.h [new file with mode: 0644]
packages/ti/sdo/ce/vidanalytics/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/vidanalytics/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/vidanalytics/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/vidanalytics/vidanalytics.c [new file with mode: 0644]
packages/ti/sdo/ce/vidanalytics/vidanalytics.h [new file with mode: 0644]
packages/ti/sdo/ce/vidanalytics/vidanalytics_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/vidanalytics/vidanalytics_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/video/IVIDDEC.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video/IVIDDEC_dsutils.xs [new file with mode: 0644]
packages/ti/sdo/ce/video/IVIDENC.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video/IVIDENC_dsutils.xs [new file with mode: 0644]
packages/ti/sdo/ce/video/VIDDECConfig.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video/VIDDECConfig.xdt [new file with mode: 0644]
packages/ti/sdo/ce/video/VIDENCConfig.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video/VIDENCConfig.xdt [new file with mode: 0644]
packages/ti/sdo/ce/video/_viddec.h [new file with mode: 0644]
packages/ti/sdo/ce/video/_videnc.h [new file with mode: 0644]
packages/ti/sdo/ce/video/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/video/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/video/viddec.c [new file with mode: 0644]
packages/ti/sdo/ce/video/viddec.h [new file with mode: 0644]
packages/ti/sdo/ce/video/viddec_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/video/viddec_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/video/videnc.c [new file with mode: 0644]
packages/ti/sdo/ce/video/videnc.h [new file with mode: 0644]
packages/ti/sdo/ce/video/videnc_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/video/videnc_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/video1/IVIDDEC1.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video1/IVIDDEC1_dsutils.xs [new file with mode: 0644]
packages/ti/sdo/ce/video1/IVIDENC1.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video1/IVIDENC1_dsutils.xs [new file with mode: 0644]
packages/ti/sdo/ce/video1/VIDDEC1Config.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video1/VIDDEC1Config.xdt [new file with mode: 0644]
packages/ti/sdo/ce/video1/VIDENC1Config.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video1/VIDENC1Config.xdt [new file with mode: 0644]
packages/ti/sdo/ce/video1/_viddec1.h [new file with mode: 0644]
packages/ti/sdo/ce/video1/_videnc1.h [new file with mode: 0644]
packages/ti/sdo/ce/video1/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/video1/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video1/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/video1/viddec1.c [new file with mode: 0644]
packages/ti/sdo/ce/video1/viddec1.h [new file with mode: 0644]
packages/ti/sdo/ce/video1/viddec1_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/video1/viddec1_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/video1/videnc1.c [new file with mode: 0644]
packages/ti/sdo/ce/video1/videnc1.h [new file with mode: 0644]
packages/ti/sdo/ce/video1/videnc1_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/video1/videnc1_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/video2/IVIDDEC2.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video2/IVIDDEC2_dsutils.xs [new file with mode: 0644]
packages/ti/sdo/ce/video2/IVIDENC2.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video2/VIDDEC2Config.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video2/VIDDEC2Config.xdt [new file with mode: 0644]
packages/ti/sdo/ce/video2/VIDENC2Config.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video2/VIDENC2Config.xdt [new file with mode: 0644]
packages/ti/sdo/ce/video2/_viddec2.h [new file with mode: 0644]
packages/ti/sdo/ce/video2/_videnc2.h [new file with mode: 0644]
packages/ti/sdo/ce/video2/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/video2/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video2/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/video2/split/IVIDDEC2BACK.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video2/split/IVIDDEC2FRONT.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video2/split/VIDDEC2BACKConfig.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video2/split/VIDDEC2BACKConfig.xdt [new file with mode: 0644]
packages/ti/sdo/ce/video2/split/_viddec2back.h [new file with mode: 0644]
packages/ti/sdo/ce/video2/split/_viddec2front.h [new file with mode: 0644]
packages/ti/sdo/ce/video2/split/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/video2/split/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video2/split/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/video2/split/viddec2.h [new file with mode: 0644]
packages/ti/sdo/ce/video2/split/viddec2back.c [new file with mode: 0644]
packages/ti/sdo/ce/video2/split/viddec2back_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/video2/split/viddec2back_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/video2/split/viddec2front.c [new file with mode: 0644]
packages/ti/sdo/ce/video2/split/viddec2front_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/video2/split/viddec2front_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/video2/viddec2.c [new file with mode: 0644]
packages/ti/sdo/ce/video2/viddec2.h [new file with mode: 0644]
packages/ti/sdo/ce/video2/viddec2_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/video2/viddec2_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/video2/videnc2.c [new file with mode: 0644]
packages/ti/sdo/ce/video2/videnc2.h [new file with mode: 0644]
packages/ti/sdo/ce/video2/videnc2_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/video2/videnc2_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/video3/IVIDDEC3.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video3/VIDDEC3Config.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video3/VIDDEC3Config.xdt [new file with mode: 0644]
packages/ti/sdo/ce/video3/_viddec3.h [new file with mode: 0644]
packages/ti/sdo/ce/video3/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/video3/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/video3/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/video3/viddec3.c [new file with mode: 0644]
packages/ti/sdo/ce/video3/viddec3.h [new file with mode: 0644]
packages/ti/sdo/ce/video3/viddec3_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/video3/viddec3_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/vidtranscode/IVIDTRANSCODE.xdc [new file with mode: 0644]
packages/ti/sdo/ce/vidtranscode/_vidtranscode.h [new file with mode: 0644]
packages/ti/sdo/ce/vidtranscode/package.bld [new file with mode: 0644]
packages/ti/sdo/ce/vidtranscode/package.xdc [new file with mode: 0644]
packages/ti/sdo/ce/vidtranscode/package.xs [new file with mode: 0644]
packages/ti/sdo/ce/vidtranscode/vidtranscode.c [new file with mode: 0644]
packages/ti/sdo/ce/vidtranscode/vidtranscode.h [new file with mode: 0644]
packages/ti/sdo/ce/vidtranscode/vidtranscode_skel.c [new file with mode: 0644]
packages/ti/sdo/ce/vidtranscode/vidtranscode_stubs.c [new file with mode: 0644]
packages/ti/sdo/ce/visa.c [new file with mode: 0644]
packages/ti/sdo/ce/visa.h [new file with mode: 0644]
products.mak [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..8c60566
--- /dev/null
@@ -0,0 +1,22 @@
+# General
+*.patch
+
+# BIOS stuff
+package/
+lib/
+bin/
+.libraries*
+.dlls
+.executables
+.interfaces
+.xdcenv.mak
+package.mak
+*.tar.gz
+
+# Linux stuff
+/autom4te.cache
+/config.log
+/config.status
+/libtool
+.deps/
+/Makefile
diff --git a/ce-bios.bld b/ce-bios.bld
new file mode 100644 (file)
index 0000000..dab234c
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2011-2013, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * *  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * *  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * *  Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Generally there is no need to edit this file!
+ *
+ * This file controls which libraries are built, as well as compiler options
+ * to use.
+ */
+
+/*
+ *  ======== ce.bld ========
+ *  This script is run prior to all build scripts. It sets host-system-
+ *  independent values for targets and platforms, then it attempts to
+ *  find the host-system-specific user.bld script that sets rootDirs.
+ *
+ *  These settings may be a function of the following global variables:
+ *
+ *      environment a hash table of environment strings
+ *
+ *      arguments   an array of string arguments to the script
+ *                  initialized as follows:
+ *                      arguments[0] - the file name of the script
+ *                      arguments[1] - the first argument specified in XDCARGS
+ *                          :
+ *                      arguments[n] - the n'th argument in XDCARGS
+ *
+ *      Build       an alias for xdc.om.xdc.bld.BuildEnvironment
+ */
+
+var Build = xdc.useModule('xdc.bld.BuildEnvironment');
+var Pkg = xdc.useModule('xdc.bld.PackageContents');
+
+/* Common ccopts suffix used for all C6x targets */
+var c6xOpts = " -mi10 -mo -pdr -pden -pds=238 -pds=880 -pds1110 -g ";
+
+/*
+ * -mi10 => maximum cycles that interrupts may be disabled is 10
+ * -mo => place each function in subsection
+ * -pdr => show remarks
+ * -pden => show remark ids
+ * -pds=238 => ignore "controlling expression is constant"
+ * -pds=880 => ignore "unused parameter"
+ */
+
+var ccOpts = {
+    "ti.targets.C64P"                 : c6xOpts,
+    "ti.targets.C674"                 : c6xOpts,
+
+    "ti.targets.elf.C64P"             : c6xOpts,
+    "ti.targets.elf.C64T"             : c6xOpts,
+    "ti.targets.elf.C66"              : c6xOpts,
+//    "ti.targets.elf.C66_big_endian"   : c6xOpts,
+    "ti.targets.elf.C674"             : c6xOpts,
+    "ti.targets.arm.elf.M3"           : " -ms -g ",
+    "ti.targets.arm.elf.M4"           : " -ms -g ",
+};
+
+var lnkOpts = {
+};
+
+var platform = "";
+
+/* initialize local vars with those set in products.mak (via XDCARGS) */
+for (arg = 0; arg < arguments.length; arg++) {
+    /* split each arg into its '+' separated parts */
+    var configParts = arguments[arg].split(";");
+    // print("arg " + arg + " has " + configParts.length + " parts");
+
+    /* if "known args come in, filter them... else they're targets */
+    if (configParts[0].split("=")[0] == "PLATFORM") {
+        // print("FOUND PLATFORM ARG - " + configParts[0]);
+        platform = configParts[0].split("=")[1];
+        continue;
+    }
+
+    /*
+     * Get the compiler's installation directory.
+     * For "ti.targets.elf.C674=/vendors/c6x/7.2.0", we get "/vendors/c6x/7.2.0"
+     */
+    var targetName = configParts[0].split("=")[0];
+    var rootDir = configParts[0].split("=")[1];
+
+    /* only build for the specified compilers */
+    if (rootDir == "" || rootDir == undefined) {
+        continue;
+    }
+
+//    print("Building '" + targetName + "' using '" + rootDir + "' ...");
+
+    var target = xdc.useModule(targetName);
+    target.rootDir = rootDir;
+
+    if (ccOpts[targetName] != undefined) {
+        target.ccOpts.suffix += ccOpts[targetName];
+    }
+    if (lnkOpts[targetName] != undefined) {
+        target.lnkOpts.suffix += lnkOpts[targetName];
+    }
+
+    /* for all the other parts, assign target.<left> = <right> */
+    for (var i = 1; i < configParts.length; i++) {
+        var modCfgParam = configParts[i].split("=")[0];
+        var modCfgValue = configParts[i].substring(configParts[i].indexOf("=") + 1);
+        var modCfgIndex = modCfgParam.split(".");
+        var element = target;
+
+//        print("Configuring target." + modCfgParam + " = " + modCfgValue);
+
+        for (j = 0; j < (modCfgIndex.length -1); j++) {
+                element = element[modCfgIndex[j]];
+        }
+        element[modCfgIndex[j]] = modCfgValue;
+    }
+
+    /* and finally add this target to the Build.targets array */
+    Build.targets.$add(target);
+}
+
+/* lib/ is a generated directory that 'xdc clean' should remove */
+Pkg.generatedFiles.$add("lib/");
+
+/* only build debug and release profiles */
+for (var t = 0; t < Build.targets.length; t++) {
+    for (prof in Build.targets[t].profiles) {
+        if ((prof != 'release') && (prof != 'debug')) {
+            delete Build.targets[t].profiles[prof];
+        }
+    }
+}
+
+
+/* -----------------------------------------------------------------------*/
+/* make release files '.tar.gz' files (.tar is default) */
+Pkg.attrs.compress = true;
diff --git a/ce-bios.mak b/ce-bios.mak
new file mode 100644 (file)
index 0000000..e1a7473
--- /dev/null
@@ -0,0 +1,141 @@
+#
+#   Copyright (c) 2012-2013, Texas Instruments Incorporated
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#   *  Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#
+#   *  Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in the
+#      documentation and/or other materials provided with the distribution.
+#
+#   *  Neither the name of Texas Instruments Incorporated nor the names of
+#      its contributors may be used to endorse or promote products derived
+#      from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+#   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+#   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+#   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+#   EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# ==== Standard Variables ====
+#
+
+# These vars are used when installing CE content
+DESTDIR ?= <UNDEFINED>
+packagesdir ?= /packages
+libdir ?= /lib
+includedir ?= /include
+ifeq ($(docdir),)
+    docdir := /share/ti/codec_engine/doc
+    packagedocdir := /docs/codec_engine
+else
+    packagedocdir := $(docdir)
+endif
+
+ifeq ($(prefix),)
+    prefix := /usr
+    packageprefix := /
+else
+    packageprefix := $(prefix)
+endif
+
+include ./products.mak
+
+#
+# Set XDCOPTIONS.  Use -v for a verbose build.
+#
+#XDCOPTIONS=v
+export XDCOPTIONS
+
+# Set XDCARGS to some of the variables above.  XDCARGS are passed
+# to the XDC build engine... which will load ce-bios.bld... which will
+# extract these variables and use them to determine what to build and which
+# toolchains to use.
+#
+# Note that not all of these variables need to be set to something valid.
+# Unfortunately, since these vars are unconditionally assigned, your build line
+# will be longer and more noisy than necessary (e.g., it will include C66
+# assignment even if you're just building for C64P).
+#
+# Some background is here:
+#     http://rtsc.eclipse.org/docs-tip/Command_-_xdc#Environment_Variables
+#
+XDCARGS= \
+    PLATFORM=\"$(PLATFORM)\" \
+    ti.targets.C64P=\"$(ti.targets.C64P)\" \
+    ti.targets.C674=\"$(ti.targets.C674)\" \
+    ti.targets.arm.elf.M3=\"$(ti.targets.arm.elf.M3)\" \
+    ti.targets.arm.elf.M4=\"$(ti.targets.arm.elf.M4)\" \
+    ti.targets.elf.C64P=\"$(ti.targets.elf.C64P)\" \
+    ti.targets.elf.C64T=\"$(ti.targets.elf.C64T)\" \
+    ti.targets.elf.C66=\"$(ti.targets.elf.C66)\" \
+    ti.targets.elf.C674=\"$(ti.targets.elf.C674)\"
+
+#    ti.targets.elf.C66_big_endian=\"$(ti.targets.elf.C66_big_endian)\"
+
+#
+# Get list of packages to rebuild.  Using LIST allows SDKs to only build
+# a subset of packages if they want to.  Default behavior builds all
+# packages.
+#
+LIST = $(shell $(XDC_INSTALL_DIR)/bin/xdcpkg ./packages)
+
+# Set XDCPATH to contain necessary repositories.
+XDCPATH = $(XDAIS_INSTALL_DIR)/packages;$(BIOS_INSTALL_DIR)/packages;$(CMEM_INSTALL_DIR)/packages;$(LINK_INSTALL_DIR)/packages;$(OSAL_INSTALL_DIR)/packages;$(FC_INSTALL_DIR)/packages;$(EDMA3_LLD_INSTALL_DIR)/packages;$(IPC_INSTALL_DIR)/packages
+export XDCPATH
+
+#
+# Set XDC executable command
+# Note that XDCBUILDCFG points to the ce-bios.bld file which uses
+# the arguments specified by XDCARGS
+#
+XDC = $(XDC_INSTALL_DIR)/xdc XDCARGS="$(XDCARGS)" XDCBUILDCFG=./ce-bios.bld
+
+######################################################
+## Shouldnt have to modify anything below this line ##
+######################################################
+
+all:
+       @ echo building ipc packages ...
+# build everything in the Bios IPC package
+       @ $(XDC) -P $(LIST)
+
+libs:
+       @echo "#"
+       @echo "# Making $@ ..."
+       $(XDC) .libraries -P $(LIST)
+#      $(XDC) .dlls -P $(LIST)
+       misraListErrors packages/misra > misraReport.txt
+
+release:
+       @ echo building ipc packages ...
+# create a XDC release for the Bios IPC package
+       @ $(XDC) release -P $(LIST)
+
+# This cleans all packages rooted in ./packages
+clean:
+       @ echo cleaning fc packages ...
+       @ $(XDC) clean -Pr ./packages
+
+install-packages:
+       @ echo installing packages to $(DESTDIR) ...
+       @ mkdir -p $(DESTDIR)/$(packageprefix)/$(packagedocdir)
+       @ cp -rf $(wildcard ipc_*_release_notes.html) docs/* $(DESTDIR)/$(packageprefix)/$(packagedocdir)
+       @ mkdir -p $(DESTDIR)/$(packageprefix)/$(packagesdir)
+       @ cp -rf packages/* $(DESTDIR)/$(packageprefix)/$(packagesdir)
+
+# Nothing for this Linux goal
+install:
diff --git a/packages/ti/sdo/ce/CERuntime.h b/packages/ti/sdo/ce/CERuntime.h
new file mode 100644 (file)
index 0000000..25bce5f
--- /dev/null
@@ -0,0 +1,511 @@
+/*
+ * Copyright (c) 2013, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * *  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * *  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * *  Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/*
+ *  ======== ti/sdo/ce/CERuntime.h ========
+ */
+
+/**
+ *  @file       ti/sdo/ce/CERuntime.h
+ *
+ *  @brief      The Codec Engine Runtime init module.  Provides system
+ *              wide initialization of the Codec Engine Runtime.
+ */
+/**
+ *  @addtogroup   CODECENGINE     Codec Engine Runtime
+ */
+
+#ifndef CERuntime_
+#define CERuntime_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @ingroup    CODECENGINE */
+/*@{*/
+
+#include <ti/sdo/ce/Engine.h>
+
+
+/* Define this symbol so alg table for an engine can be NULL */
+#define CE_NULL_algs NULL
+
+/**
+ *  @brief      Macros for runtime configuration. These macros can be used to
+ *              create a static table of algorithms.  However, the preferred
+ *              method of building engine and alg tables, is to use the
+ *              run-time APIs, Engine_add() and Engine_addAlg().
+ *
+ *  @sa Engine_add()
+ *  @sa Engine_addAlg()
+ */
+
+/*
+ *  ======== CE_DECLARE_TYPE ========
+ */
+/**
+ *  @brief      Declare an inheritanc hierarchy for an algorithm.
+ *
+ *  @param[in]  name    This is a symbol that will be associated with the
+ *                      @c types argument. It will be used to generate an
+ *                      internal variable name, so don't use the same name
+ *                      for two different calls to @c CE_DECLARE_TYPE().
+ *                      @c name should be used in CE_LOCAL_ALG() to
+ *                      associate an alg to @c types.
+ *
+ *  @param[in]  types   This is a ';' separated string of inheritance
+ *                      hierarchies. It is used to identify the codec class of
+ *                      an algorithm. For example, the declaration:
+ *                      @c CE_DECLARE_TYPE(mydecoder,
+ *                                         "ti.sdo.ce.speech1.ISPHDEC1")
+ *                      indicates that mydecoder (a name that will be used
+ *                      in CE_LOCAL_ALG() to declare a speech decoder),
+ *                      inherits the ti.sdo.ce.speech1.ISPHDEC1 interface.
+ *
+ *                      Another example is the following:
+ *                      CE_DECLARE_TYPE(decoder,
+ *                      "ti.sdo.ce.video.IVIDDEC;ti.sdo.ce.test.xvideo.IVIDE")
+ *                      This says that the decoder inherits the
+ *                      ti.sdo.ce.test.xvideo.IVIDE interface, which in turn
+ *                      inherits the ti.sdo.ce.video.IVIDDEC interface.
+ *
+ *  @deprecated No need to use this macro when using CE_LOCAL_ALG2
+ *
+ *  @sa CE_LOCAL_ALG2()
+ */
+#define CE_DECLARE_TYPE(name, types)         \
+                                             \
+static String typeTab_##name [] = {          \
+    (types),                                 \
+    NULL                                     \
+};                                           \
+                                             \
+/*
+ *  ======== CE_LOCAL_ALG ========
+ */
+/**
+ *  @brief      Generates a structure containing data for a local algorithm.
+ *
+ *  @param[in]  name      This symbol is used to associate the algorithm with
+ *                        one of the @c types passed to @c CE_DECLARE_TYPE().
+ *  @param[in]  algName   This is the string name that the applicaion will use
+ *                        to create the algorithm, for example, "sphenc1_copy".
+ *  @param[in]  ialgFxns  The address of the IALG_Fxns table for the algorithm.
+ *  @param[in]  idma3Fxns The address of the algorithm's IDMA3_Fxns table, if
+ *                        it has one, otherwise NULL.
+ *  @param[in]  iresFxns  If the algorithm uses IRES, the address of its
+ *                        IRES_Fxns table, otherwise NULL.
+ *  @param[in]  groupId   Scratch group Id of algorithm.
+ *  @param[in]  memType   The type of memory (cached, non-cached, or whatever
+ *                        the default is), to allocate for the algorithm.
+ *                        Choose from the following values for memType:
+ *
+ *                 Engine_USECACHEDMEM_DEFAULT - default memory allocation
+ *                 Engine_USECACHEDMEM_NONCACHED - non-cached memory allocation
+ *                 Engine_USECACHEDMEM_CACHED - cached memory allocation
+ *
+ *  @par Example Usage:
+ *  @code
+ *      CE_BEGIN_ALG_TABLE(engineName)
+ *          CE_LOCAL_ALG(name_1, ...)
+ *          CE_LOCAL_ALG(name_2, ...)
+ *          ...
+ *          CE_LOCAL_ALG(name_n, ...)
+ *      CE_END_ALG_TABLE(engineName)
+ *  @endcode
+ *
+ * @remarks     This macro must be called between the @c CE_BEGIN_ALG_TABLE()
+ *              and @c CE_END_ALG_TABLE() macro calls.
+ *
+ *  @deprecated Use CE_LOCAL_ALG2 instaead.
+ *
+ *  @sa CE_DECLARE_TYPE
+ *  @sa CE_BEGIN_ALG_TABLE
+ */
+#define CE_LOCAL_ALG(name, algName, ialgFxns, idma3Fxns, iresFxns, groupId, \
+                     memType) \
+                                             \
+    { (algName),      /* name */             \
+      {0},            /* uuid */             \
+      (ialgFxns),     /* ialgFxns */         \
+      (idma3Fxns),    /* idma3Fxns */        \
+      typeTab_##name, /* typeTab */          \
+      TRUE,           /* isLocal */          \
+      (groupId),      /* groupId */          \
+      0,              /* protocol */         \
+      (iresFxns),     /* iresFxns */         \
+      NULL,           /* stub/skel params */ \
+      (memType),      /* cached mem type */  \
+      NULL,           /* type - typeTab[0] will be used instead */ \
+    },
+
+/*
+ *  ======== CE_LOCAL_ALG2 ========
+ */
+/**
+ *  @brief      Generates a structure containing data for a local algorithm.
+ *              This macro takes a 'types' string as an argument to avoid
+ *              having to use the CE_DECLARE_TYPES() macro call.
+ *
+ *  @param[in]  algName   This is the string name that the applicaion will use
+ *                        to create the algorithm, for example, "sphenc1_copy".
+ *  @param[in]  ialgFxns  The address of the IALG_Fxns table for the algorithm.
+ *  @param[in]  idma3Fxns The address of the algorithm's IDMA3_Fxns table, if
+ *                        it has one, otherwise NULL.
+ *  @param[in]  iresFxns  If the algorithm uses IRES, the address of its
+ *                        IRES_Fxns table, otherwise NULL.
+ *  @param[in]  groupId   Scratch group Id of algorithm.
+ *  @param[in]  memType   The type of memory (cached, non-cached, or whatever
+ *                        the default is), to allocate for the algorithm.
+ *                        Choose from the following values for memType:
+ *
+ *                 Engine_USECACHEDMEM_DEFAULT - default memory allocation
+ *                 Engine_USECACHEDMEM_NONCACHED - non-cached memory allocation
+ *                 Engine_USECACHEDMEM_CACHED - cached memory allocation
+ *  @param[in]  types     The ';' separated string of inheritance
+ *                        hierarchies. This must be constant in order to
+ *                        initialize the structure.
+ *
+ *  @par Example Usage:
+ *  @code
+ *      CE_BEGIN_ALG_TABLE(engineName)
+ *          CE_LOCAL_ALG(name_1, ...)
+ *          CE_LOCAL_ALG(name_2, ...)
+ *          ...
+ *          CE_LOCAL_ALG(name_n, ...)
+ *      CE_END_ALG_TABLE(engineName)
+ *  @endcode
+ *
+ * @remarks     This macro must be called between the @c CE_BEGIN_ALG_TABLE()
+ *              and @c CE_END_ALG_TABLE() macro calls.
+ *
+ *  @sa CE_DECLARE_TYPE
+ *  @sa CE_BEGIN_ALG_TABLE
+ */
+#define CE_LOCAL_ALG2(algName, ialgFxns, idma3Fxns, iresFxns, groupId, \
+                     memType, types) \
+                                             \
+    { (algName),      /* name */             \
+      {0},            /* uuid */             \
+      (ialgFxns),     /* ialgFxns */         \
+      (idma3Fxns),    /* idma3Fxns DEPRECATED */        \
+      NULL,           /* typeTab */          \
+      TRUE,           /* isLocal */          \
+      (groupId),      /* groupId */          \
+      0,              /* protocol */         \
+      (iresFxns),     /* iresFxns */         \
+      NULL,           /* stub/skel params */ \
+      (memType),      /* cached mem type */  \
+      (types),        /* types */            \
+    },
+
+/*
+ *  ======== CE_DECLARE_LOCAL_ALG ========
+ */
+/**
+ *  @brief      Generates a static variable of type Engine_AlgDesc.
+ *              It is used in this manner:
+ *
+ *  @param[in]  name      The name to be given to the static Engine_AlgDesc
+ *                        variable.
+ *  @param[in]  algName   This is the string name that the applicaion will use
+ *                        to create the algorithm, for example, "sphenc1_copy".
+ *  @param[in]  ialgFxns  The address of the IALG_Fxns table for the algorithm.
+ *  @param[in]  idma3Fxns The address of the algorithm's IDMA3_Fxns table, if
+ *                        it has one, otherwise NULL. (DEPRECATED)
+ *  @param[in]  iresFxns  If the algorithm uses IRES, the address of its
+ *                        IRES_Fxns table, otherwise NULL.
+ *  @param[in]  groupId   Scratch group Id of algorithm.
+ *  @param[in]  memType   The type of memory (cached, non-cached, or whatever
+ *                        the default is), to allocate for the algorithm.
+ *                        Choose from the following values for memType:
+ *
+ *                 Engine_USECACHEDMEM_DEFAULT - default memory allocation
+ *                 Engine_USECACHEDMEM_NONCACHED - non-cached memory allocation
+ *                 Engine_USECACHEDMEM_CACHED - cached memory allocation
+ *  @param[in]  types     The ';' separated string of inheritance
+ *                        hierarchies. This must be constant in order to
+ *                        initialize the structure.
+ *
+ *  @par Example Usage:
+ *  @code
+ *      CE_DECLARE_LOCAL_ALG(algName, )
+ *
+ *      main()
+ *      {
+ *          ...
+ *          status = Engine_addAlgDesc(engine, algName);
+ *          ...
+ *      }
+ *  @endcode
+ *
+ */
+#define CE_DECLARE_LOCAL_ALG(name, algName, ialgFxns, idma3Fxns, iresFxns, \
+                     groupId, memType, types) \
+static Engine_AlgDesc (name) = \
+                                             \
+    { (algName),      /* name */             \
+      {0},            /* uuid */             \
+      (ialgFxns),     /* ialgFxns */         \
+      (idma3Fxns),    /* idma3Fxns (DEPRECATED) */        \
+      NULL,           /* typeTab */          \
+      TRUE,           /* isLocal */          \
+      (groupId),      /* groupId */          \
+      0,              /* protocol */         \
+      (iresFxns),     /* iresFxns */         \
+      NULL,           /* stub/skel params */ \
+      (memType),      /* cached mem type */  \
+      (types),        /* types */            \
+    };
+
+
+/*
+ *  ======== CE_BEGIN_ALG_TABLE ========
+ */
+/**
+ *  @brief      Use this macro and the CE_END_ALG_TABLE() macro around
+ *              CE_LOCAL_ALG() to generate an algorithm table for an engine.
+ *
+ *  @param[in]  name  A symbol used to generate internal variable names.
+ *                    Use the same name in CE_END_ALG_TABLE(), and in
+ *                    the call to CE_ENGINE(), to associate an engine
+ *                    with this algorithm table.
+ *
+ *  @par Example Usage:
+ *  @code
+ *      CE_BEGIN_ALG_TABLE(engineAlgTab)
+ *          CE_LOCAL_ALG(name_1, ...)
+ *          CE_LOCAL_ALG(name_2, ...)
+ *          ...
+ *          CE_LOCAL_ALG(name_n, ...)
+ *      CE_END_ALG_TABLE(engineAlgTab)
+ *  @endcode
+ *
+ *  @sa CE_END_ALG_TABLE()
+ *  @sa CE_ENGINE()
+ */
+/*
+#define CE_BEGIN_ALG_TABLE(name)        \
+static Engine_AlgDesc CE_##name##_algs[] = {
+*/
+
+#define ALG_TABLE_NAME_LHS(name) CE_##name
+
+#define ALG_TABLE_RHS(name) name##_algs[]
+
+#define CE_BEGIN_ALG_TABLE(name) \
+static Engine_AlgDesc ALG_TABLE_RHS(ALG_TABLE_LHS(name))
+
+/*
+ *  ======== CE_END_ALG_TABLE ========
+ */
+/**
+ *  @brief      Use this macro after CE_BEGIN_ALG_TABLE() and CE_LOCAL_ALG()
+ *              for generating an algorithm table for an engine.
+ *
+ *  @param[in]  name  This must be the same symbol name passed to the
+ *                    previous @c CE_BEGIN_ALG_TABLE() call.
+ *
+ *  @par Example Usage:
+ *  @code
+ *      CE_BEGIN_ALG_TABLE(engineAlgTab)
+ *          CE_LOCAL_ALG(name_1, ...)
+ *          CE_LOCAL_ALG(name_2, ...)
+ *          ...
+ *          CE_LOCAL_ALG(name_n, ...)
+ *      CE_END_ALG_TABLE(engineAlgTab)
+ *  @endcode
+ *
+ *  @sa CE_BEGIN_ALG_TABLE
+ *  @sa CE_ENGINE
+ */
+#define CE_END_ALG_TABLE(name) \
+    {NULL},                    \
+};
+
+/*
+ *  ======== CE_ENGINE ========
+ */
+/**
+ *  @brief      Generates a structure containing data for an engine.
+ *
+ *  @param[in]  algTab      Symbol to associate an alg table to this engine.
+ *                          Use the name passed to CE_BEGIN_ALG_TABLE() to
+ *                          associate that alg table with this engine.
+ *  @param[in]  engName     The name of the engine to open
+ *  @param[in]  serverName  The name of the Server image to load (if any).
+ *                          On SysLink-based systems, this is the name of a
+ *                          file and is passed unchanged to ProcMgr_Load().
+ *  @param[in]  memMap      The name of a memory map (if any).
+ *                          On SysLink-based systems, this file is used to
+ *                          map slave memory into the MMU using ProcMgr_map().
+ *  @param[in]  useExtLoader  Set to TRUE if an external loader will be used
+ *                          to load the server.  If set to FALSE, Codec Engine
+ *                          will load the server when the Engine is opened.
+ *  @param[in]  heapId      Optional heap id to be used for this Engine. This
+ *                          is used internally, for example, by Comm_alloc().
+ *                          Use a value of 0 for heapId as the default.
+ *
+ *  @remarks    This macro must be called between the @c CE_BEGIN_ENGINE_TABLE()
+ *              and @c CE_END_ENGINE_TABLE() macro calls.
+ *
+ *  @par Example Usage:
+ *  @code
+ *      CE_BEGIN_ENGINE_TABLE(name)
+ *          CE_ENGINE(algTab_0, "engine_0", NULL, 0)
+ *          CE_ENGINE(algTab_1, "engine_1", "server.x64P", 0)
+ *      CE_END_ENGINE_TABLE(name)
+ *  @endcode
+ *
+ *  @sa CE_BEGIN_ALG_TABLE
+ *  @sa CE_BEGIN_ENGINE_TABLE
+ */
+#define CE_ENGINE(algTab, engName, serverName, memMap, useExtLoader, heapId) \
+    { (engName),          /* engine name */                      \
+      CE_##algTab##_algs, /* alg table */                        \
+      (serverName),       /* optional server name */             \
+      NULL,               /* memMap */                           \
+      0,                  /* useExtLoader */                     \
+      0,                  /* # of algs (filled in at runtime) */ \
+      (heapId)            /* heapId */                           \
+    },
+
+
+/*
+ *  ======== CE_BEGIN_ENGINE_TABLE ========
+ */
+/**
+ *  @brief      Use this macro and the CE_END_ENGINE_TABLE() macro around
+ *              CE_ENGINE() to generate an engine table for the application.
+ *
+ *              The usage is:
+ *              CE_BEGIN_ENGINE_TABLE(name)
+ *                  CE_ENGINE(algTab_1, ...)
+ *                  CE_ENGINE(algTab_2, ...)
+ *                  ...
+ *                  CE_ENGINE(algTab_n, ...)
+ *              CE_END_ENGINE_TABLE(name)
+ *
+ *  @param[in]  name  A symbol used to generate internal variable
+ *                    names. Use the same name in CE_END_ENGINE_TABLE().
+ *
+ *  @sa CE_END_ENGINE_TABLE
+ *  @sa CE_ENGINE
+ */
+#define CE_BEGIN_ENGINE_TABLE(name) \
+static Engine_AlgDesc _localAlgs_000[] = {    \
+    {NULL},                                   \
+};                                            \
+                                              \
+static Engine_Desc name##_000[] = {
+
+/*
+ *  ======== CE_END_ENGINE_TABLE ========
+ */
+/**
+ *  @brief      Use this macro and the CE_BEGIN_ENGINE_TABLE() macro around
+ *              CE_ENGINE() to generate an engine table for the application.
+ *
+ *              The usage is:
+ *              CE_BEGIN_ENGINE_TABLE(name)
+ *                  CE_ENGINE(algTab_1, ...)
+ *                  CE_ENGINE(algTab_2, ...)
+ *                  ...
+ *                  CE_ENGINE(algTab_n, ...)
+ *              CE_END_ENGINE_TABLE(name)
+ *
+ *  @param[in]  name  A symbol used to generate internal variable
+ *                    names. Use the same name in CE_BEGIN_ENGINE_TABLE().
+ *
+ *  @sa CE_BEGIN_ENGINE_TABLE
+ *  @sa CE_ENGINE
+ */
+#define CE_END_ENGINE_TABLE(name)             \
+    {"local",                                 \
+     _localAlgs_000,                          \
+     NULL,                                    \
+     NULL,                                    \
+     0,                                       \
+    },                                        \
+    {NULL, NULL, NULL, NULL, 0}               \
+};                                            \
+                                              \
+Engine_Config Engine_config = {               \
+    name##_000,                               \
+    "local"                                   \
+};
+
+/*
+ *  ======== CERuntime_exit ========
+ */
+/**
+ *  @brief      Exit the Codec Engine Runtime.
+ *
+ *  @remarks    This function finalizes the Codec Engine modules used in
+ *              the current configuration.
+ *
+ *  @sa         CERuntime_init()
+ */
+extern Void CERuntime_exit(Void);
+
+
+/*
+ *  ======== CERuntime_init ========
+ */
+/**
+ *  @brief      Initialize the Codec Engine Runtime.
+ *
+ *  @remarks    This function must be called prior to using any Codec Engine
+ *              APIs; it initializes all Codec Engine modules used in the
+ *              the current configuration.
+ *
+ *  @remarks    Note that this must be called for both applications and
+ *              [if applicable] Servers.
+ *
+ *  @remarks    For Servers, this is typically called from main().
+ *
+ *  @pre        For Servers, Ipc_start() must be called prior to calling
+ *              CERuntime_init().  See the examples' main() implementation for
+ *              reference.
+ *
+ *  @sa         CERuntime_exit()
+ */
+extern Void CERuntime_init(Void);
+
+/*@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/packages/ti/sdo/ce/CERuntime.xdc b/packages/ti/sdo/ce/CERuntime.xdc
new file mode 100644 (file)
index 0000000..9274726
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2013, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * *  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * *  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * *  Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/*!
+ *  ======== CERuntime ========
+ *  Global Codec Engine Runtime
+ *
+ *  @_nodoc
+ */
+@Template("./CERuntime.xdt")
+
+metaonly module CERuntime {
+
+    /*!
+     * ======== addInitCode ========
+     * adds code (text) to be called from CERuntime's init() function
+     *
+     * @_nodoc
+     */
+    Void addInitCode(String initCodeLines, bool addEarly);
+}
diff --git a/packages/ti/sdo/ce/CERuntime.xdt b/packages/ti/sdo/ce/CERuntime.xdt
new file mode 100644 (file)
index 0000000..976a295
--- /dev/null
@@ -0,0 +1,278 @@
+%%{
+/*
+ * Copyright (c) 2013, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * *  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * *  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * *  Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+%%}
+%%{
+    /*
+     *  ======== CERuntime.xdt ========
+     *  Generate initialization backplace for the Codec Engine
+     */
+
+    var Server = this.$package.Server;
+    var Engine = this.$package.Engine;
+    var Settings = this.$package.Settings;
+
+    var ipcSettings = xdc.module('ti.sdo.ce.ipc.Settings');
+
+    // Get the name of the ipc module
+    var ipcName = ipcSettings.ipc.$name;
+
+    // Determine if the ipc has a property called "useLinkArbiter", and if it
+    // does, set the value of the variable useLinkArbiterProp to true. If it
+    // does not, we will generate the symbol Global_useLinkArbiter.
+    var ipc = xdc.module(ipcName);
+
+    var useLinkArbiterProp = false;
+    if ("useLinkArbiter" in ipc) {
+        //print("Server.xdt: ipc *has* property useLinkArbiter");
+        useLinkArbiterProp = true;
+    }
+    else {
+        //print("Server.xdt: ipc does *not* have property useLinkArbiter");
+    }
+
+    var isBios = ((Program.build.target.os == undefined) ? true : false);
+%%}
+
+#include <xdc/std.h>
+#include <xdc/runtime/Diags.h>
+
+#include <ti/sdo/ce/global/CESettings.h>
+#include <ti/sdo/fc/global/FCSettings.h>
+
+#include <ti/sdo/ce/osal/Global.h>
+#include <ti/sdo/ce/ipc/Comm.h>
+#include <ti/sdo/ce/osal/Loader.h>
+#include <ti/sdo/ce/osal/Memory.h>
+#include <ti/sdo/ce/osal/Queue.h>
+#include <ti/sdo/ce/osal/Trace.h>
+#include <ti/sdo/ce/ipc/Processor.h>
+#include <ti/sdo/ce/alg/Algorithm.h>
+#include <ti/sdo/ce/Server.h>
+#include <ti/sdo/ce/Engine.h>
+#include <ti/sdo/ce/rms.h>
+#include <ti/sdo/ce/utils/xdm/XdmUtils.h>
+
+% // If the symbol Global_useLinkArbiter is not defined by the ipc (eg, for
+% // ce.ipc.linux), we need to define this symbol and set it to FALSE. The
+% // function Server_init() references this symbol for v5T targets.
+% if (!useLinkArbiterProp) {
+/* This symbol is referenced by Server_init() */
+Int Global_useLinkArbiter = FALSE;
+% }
+
+%// Hopefully temporary workaround for 'whole_program' profiles which
+%// optimize away these generated fxns.  :(
+#ifdef __ti__
+    #pragma FUNC_EXT_CALLED(CERuntime_init);
+    #pragma FUNC_EXT_CALLED(CERuntime_exit);
+#endif
+
+#ifdef xdc_target__os_Linux
+
+#include <pthread.h>
+
+static pthread_mutex_t ceInitMutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
+static Int ceInit = 0;
+
+/*
+ *  ======== CERuntime_init ========
+ */
+Void CERuntime_init(Void)
+{
+#ifdef xdc_target__os_Linux
+    pthread_mutex_lock(&ceInitMutex);
+#endif
+
+    if (ceInit++ == 0) {
+
+        CESettings_init();
+% if (isBios) {
+        FCSettings_init();
+% }
+
+% if (Settings.checked) {
+        /* Checked build enabled, turn on trace level 7 */
+        // TODO: GT_set("*+7");
+% }
+
+        /* if CE_DEBUG is set, turn on tracing and DSP auto trace collection */
+        if (Global_getenv("CE_DEBUG") != NULL) {
+            extern Bool   Engine_alwaysCollectDspTrace;
+            extern String Engine_ceDebugDspTraceMask;
+
+            Engine_alwaysCollectDspTrace = TRUE;
+
+            /*
+             * Note the strategy for setting trace masks below...
+             * For any mods not yet registered, we set the
+             * [FC|CE]SETTINGS_MODNAME mask.  For any mods already
+             * registered, we Diags_setMask() them.
+             */
+
+            if (Global_getenv("CE_DEBUG")[0] == '1') {
+                /* Turn on CE/FC levels 6 and 7 */
+                xdc_runtime_Diags_setMask(CESETTINGS_MODNAME"+67");
+                xdc_runtime_Diags_setMask(FCSETTINGS_MODNAME"+67");
+                xdc_runtime_Diags_setMask("ti.sdo.ce.%+67");
+                xdc_runtime_Diags_setMask("ti.sdo.fc.%+67");
+
+                /* Same for any Servers */
+                Engine_ceDebugDspTraceMask = "ti.sdo.ce.%+67;ti.sdo.fc.%+67";
+            }
+            else if (Global_getenv("CE_DEBUG")[0] == '2') {
+                xdc_runtime_Diags_setMask(CESETTINGS_MODNAME"+EX1234567");
+                xdc_runtime_Diags_setMask(FCSETTINGS_MODNAME"+EX1234567");
+                xdc_runtime_Diags_setMask("ti.sdo.ce.%+EX1234567");
+                xdc_runtime_Diags_setMask("ti.sdo.fc.%+EX1234567");
+
+                xdc_runtime_Diags_setMask("ti.sdo.xdcruntime.linux.%+EX1234567");
+
+                Engine_ceDebugDspTraceMask =
+                    // Current Diags mask: (time=2 ==> display time in delta usec
+                    "ti.sdo.ce.%+EX1234567;ti.sdo.fc.%+EX12345678;ti.sdo.ce.rms=67;ti.sdo.fc.dskt2-2;time=2";
+            }
+            else if (Global_getenv("CE_DEBUG")[0] == '0') {
+                /* Don't set anything if someone tries to turn CE_DEBUG off */
+            } else {
+                xdc_runtime_Diags_setMask("ti.sdo.ce.%+EX1234567");
+                xdc_runtime_Diags_setMask("ti.sdo.fc.%+EX1234567");
+                //TEMP (jeh) xdc_runtime_Diags_setMask("ti.sdo.ce.Engine-3");
+                xdc_runtime_Diags_setMask("ti.sdo.xdcruntime.linux.%+EX1234567");
+
+                Engine_ceDebugDspTraceMask =
+                    "time=2;ti.sdo.fc.%+EX1234567;ti.sdo.ce.%+EX1234567;ti.sdo.fc.dskt2-2";
+            }
+        }
+        else {
+            //xdc_runtime_Diags_setMask("ti.sdo.ce.Engine-EX1234567");
+            //xdc_runtime_Diags_setMask("ti.sdo.ce.VISA-EX1234567");
+        }
+
+        if (Global_getenv("CE_CHECK") != NULL) {
+            extern Bool VISA_checked;
+
+            /*
+             * Currently just change _this_ processor's value... perhaps we
+             * should enable remote processors as well?
+             */
+            if (Global_getenv("CE_CHECK")[0] == '1') {
+                VISA_checked = TRUE;
+                xdc_runtime_Diags_setMask("ti.sdo.ce.%+7");
+            } else if (Global_getenv("CE_CHECK")[0] == '0') {
+                VISA_checked = FALSE;
+            } else {
+                /* leave it whatever it was. maybe we should drop a warning? */
+            }
+        }
+
+        /* allow user to over-ride via CE_TRACE. */
+        if (Global_getenv("CE_TRACE") != NULL) {
+            xdc_runtime_Diags_setMask(Global_getenv("CE_TRACE"));
+        }
+        Global_init();
+
+% if (this.$private.addEarlyInitCodeText != undefined) {
+        `this.$private.addEarlyInitCodeText`
+% }
+
+        ti_sdo_ce_osal_Memory_init();
+        Comm_init();
+        Processor_init();
+        Algorithm_init();
+        XdmUtils_init();
+
+%if (Server.$used) {
+        Trace_init();
+        RMS_init();
+        Global_atexit((Fxn)RMS_exit);
+%}
+%if (Engine.$used) {
+        Engine_init();
+        _VISA_init();
+        Loader_init();
+       Server_init();
+%}
+        if ((Global_getenv("CE_DEBUG") != NULL) &&
+                (Global_getenv("CE_DEBUG")[0] == '2')) {
+
+            /*
+             *  set up masks that must be deferred until the modules have been
+             *  initialized.
+             */
+            //xdc_runtime_Diags_setMask(Comm_MODNAME"-EX12345");
+            xdc_runtime_Diags_setMask("ti.sdo.ce.osal.%-EX123");
+            //xdc_runtime_Diags_setMask(Algorithm_MODNAME"-EX12345");
+
+            xdc_runtime_Diags_setMask("ti.sdo.ce.Engine-3");
+            xdc_runtime_Diags_setMask("ti.sdo.ce.ipc.Comm=67");
+        }
+
+        /*
+         *  Allow user to over-ride via CE_TRACE. Putting this after module
+         *  initialization, since it will have no effect may have no effect
+         *  if called before. Only wildcard settings seem to work when placed
+         *  before module initialization.
+         */
+        if (Global_getenv("CE_TRACE") != NULL) {
+            xdc_runtime_Diags_setMask(Global_getenv("CE_TRACE"));
+        }
+
+% if (this.$private.addLateInitCodeText != undefined) {
+        `this.$private.addLateInitCodeText`
+            % }
+    }
+#ifdef xdc_target__os_Linux
+    pthread_mutex_unlock(&ceInitMutex);
+#endif
+}
+
+/*
+ *  ======== CERuntime_exit ========
+ */
+Void CERuntime_exit(Void)
+{
+#ifdef xdc_target__os_Linux
+    pthread_mutex_lock(&ceInitMutex);
+#endif
+
+    if (--ceInit == 0) {
+        Global_exit();
+    }
+
+#ifdef xdc_target__os_Linux
+    pthread_mutex_unlock(&ceInitMutex);
+#endif
+}
diff --git a/packages/ti/sdo/ce/CERuntime.xs b/packages/ti/sdo/ce/CERuntime.xs
new file mode 100644 (file)
index 0000000..65facec
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * *  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * *  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * *  Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+function addInitCode(initCodeLines, addEarly)
+{
+    if (addEarly) {
+        if (this.$private.addEarlyInitCodeText == undefined) {
+            this.$private.addEarlyInitCodeText = "";
+        }
+        this.$private.addEarlyInitCodeText += initCodeLines + "\n";
+    }
+    else {
+        if (this.$private.addLateInitCodeText == undefined) {
+            this.$private.addLateInitCodeText = "";
+        }
+        this.$private.addLateInitCodeText += initCodeLines + "\n";
+    }
+}
diff --git a/packages/ti/sdo/ce/Engine.c b/packages/ti/sdo/ce/Engine.c
new file mode 100644 (file)
index 0000000..c0dd5cd
--- /dev/null
@@ -0,0 +1,4131 @@
+/*
+ * Copyright (c) 2013, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * *  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * *  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * *  Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/*
+ *  ======== Engine.c ========
+ */
+
+/* This define must precede inclusion of any xdc header files */
+#define Registry_CURDESC ti_sdo_ce_Engine_desc
+
+#include <xdc/std.h>
+#include <xdc/runtime/Assert.h>
+#include <xdc/runtime/Diags.h>
+#include <xdc/runtime/Log.h>
+#include <xdc/runtime/Gate.h>
+#include <xdc/runtime/knl/GateThread.h>
+#include <xdc/runtime/Timestamp.h>
+#include <xdc/runtime/Registry.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include <ti/sdo/ce/osal/Memory.h>
+#include <ti/sdo/ce/osal/Queue.h>
+#include <ti/sdo/ce/osal/Global.h>
+
+#include <ti/sdo/ce/ipc/Comm.h>
+#include <ti/sdo/ce/ipc/Processor.h>
+
+#include <ti/sdo/ce/global/CESettings.h>
+#include <ti/sdo/ce/alg/Algorithm.h>
+
+#include <ti/sdo/ce/osal/Loader.h>
+#include <ti/sdo/ce/rms.h>
+#include <ti/sdo/ce/Engine.h>
+#include <ti/sdo/ce/node/node.h>
+
+#include <ti/sdo/ce/_Engine.h>
+
+#include <ti/xdais/ialg.h>
+
+Registry_Desc ti_sdo_ce_Engine_desc;
+
+static Int regInit = 0;     /* Registry_addModule() called */
+
+/*
+ *  Names of functions that a dynamically loaded codec must supply.
+ *
+ *  TODO: These symbol names should be global somewhere (once the names are
+ *  settled on) since dynamically loaded codec must have functions by these
+ *  names.
+ *
+ *  TODO: Should we assume the dynamically loaded codec will have only
+ *  one alg descriptor?
+ */
+#define GETNUMALGDESCFXN "GetNumEngineAlgDesc"
+#define GETALGDESCFXN  "GetEngineAlgDesc"
+
+typedef Int (*GetNumAlgDescFxn)(Void);
+typedef Int (*GetAlgDescFxn)(Engine_AlgDesc *algDescTab);
+
+typedef struct RServerObj {
+    Processor_Handle  dspProc;
+    String            imageName;
+    Int               refCount;
+} RServerObj, *RServer;
+
+/*
+ *  ======== _Engine_AlgLib ========
+ *  Structure to hold information about algs added with Engine_addAlg().
+ */
+typedef struct _Engine_AlgLib {
+    struct _Engine_AlgLib   *next;
+    Loader_Handle           lib;
+    Engine_AlgDesc          algDesc;
+
+    /* Need this to support Engine_getAlgInfo() */
+    String                  typeTab[2];
+} _Engine_AlgLib;
+
+/*
+ *  ======== Engine_Obj ========
+ */
+typedef struct Engine_Obj {
+    Queue_Elem      link;
+    RServer         server;
+    Comm_Id         toRMS;
+    Comm_Handle     fromRMS;
+    UInt16          rmsPoolId;
+    Comm_Msg        rmsMsg;
+    Engine_Desc     *desc;
+    Engine_Error    lastError;
+    Bool            hasServer;  /* TRUE <=> there is a server */
+
+    /* Filled in when Engine_initFromServer() is called */
+    Engine_AlgDesc *remoteAlgTab;
+    Int numRemoteAlgs;
+
+    _Engine_AlgLib *loadedLibs;    /* Algs added with Engine_addAlg() */
+    Int             numLoadedLibs; /* Number of algs added */
+
+    struct Engine_DescListElem *descElem;
+    String          procId;     /* server proc name */
+} Engine_Obj;
+
+/*
+ *  ======== Engine_NodeObj ========
+ */
+typedef struct Engine_NodeObj {
+    Engine_Handle   engine;
+    Comm_Id         stdIn;      /* the node's input queue */
+    Comm_Handle     stdOut;     /* the node's output queue */
+    String          impId;      /* algorithm implementation name */
+    RMS_Word        rmsNode;    /* remote node handle */
+    size_t          msgSize;    /* size of messages exchanged with node */
+    RMS_Word        remoteVisa; /* Remote visa handle */
+} Engine_NodeObj;
+
+/*
+ *  ======== Engine_DescListElem ========
+ *  Structure for queuing up Engine_Desc objects.
+ */
+typedef struct Engine_DescListElem {
+    Queue_Elem      link;
+    Engine_Desc     desc;
+
+    /*
+     *  This is a list of algs that have been added to the engine while
+     *  it is not in the 'open' state. Algs added before the engine has
+     *  been opened will be accessible to all threads opening the engine.
+     *  Once an engine has been opened, any algs added will be maintained
+     *  in the Engine handle passed to Engine_addAlg(), and will only
+     *  be accessible from the Engine handle.
+     */
+    _Engine_AlgLib *loadedLibs;    /* Algs that have been added */
+    Int             numLoadedLibs; /* Number of algs added */
+
+    Int             refCount;   /* Number of opened engines */
+
+    /*
+     *  Staticaly created engines will be put on the list too. For these
+     *  engines, we don't need to allocate buffers for the engine name
+     *  and remote name. We mark them as static, so as not to free the
+     *  names.
+     */
+    Bool            isStatic;
+} Engine_DescListElem;
+
+/*
+ *  Stub function entry that can be queued up.
+ */
+typedef struct Engine_StubFxnsElem {
+    Queue_Elem  link;
+    String      name;
+    IALG_Fxns  *stubFxns;
+} Engine_StubFxnsElem;
+
+String ti_sdo_ce__versionString = "1, 0, 6";
+
+
+/*
+ *  ======== Engine_ALGCREATEATTRS ========
+ */
+Engine_AlgCreateAttrs Engine_ALGCREATEATTRS = {
+    FALSE,      /* Use external heap */
+    -1,         /* priority */
+};
+
+Engine_Attrs Engine_ATTRS = {
+    NULL,         /* procId */
+};
+
+/*
+ *  currently static internal fxn - should this be external?
+ *  Temporarily made extern for debugging.
+ */
+extern Engine_Error Engine_getNumServerAlgs(Server_Handle server, Int *nAlgs);
+
+
+static Engine_Error addAlg(String engName, Engine_Handle engine,
+        Engine_AlgDesc *pAlgDesc, Loader_Handle lib);
+static Engine_Error addEngineToList(Engine_Desc *desc, Bool isStatic);
+static Engine_Node allocNode(Engine_Handle s, String impId);
+static RMS_Status callServer(Engine_Handle engine, Comm_Msg *msg);
+static Bool checkServer(Engine_Handle engine);
+static Void cleanup(Void);
+static Int copyToFile(Char *cp, Int size, String prefix, Bool *nl, FILE *out);
+static Void freeNode(Engine_Node node);
+static Void freeServerTab(Engine_Handle engine);
+static Engine_AlgDesc *getAlgDesc(String name, Engine_Handle engine,
+        String algName);
+static Engine_AlgDesc *getAlgDescNum(String engName, Engine_Handle engine,
+        Int index);
+static Engine_DescListElem *getDescListElem(String name);
+static String getServerKey(Engine_Handle engine);
+static IALG_Fxns *getStubFxns(String stubFxnsName);
+static Bool isa(Engine_AlgDesc *alg, String type);
+static Void name2Uuid(Engine_Obj *engine, String name, NODE_Uuid *uuid);
+static Engine_Handle rmsInit(Engine_Obj *engine, Engine_Error *ec);
+static Int getRpcProtocolVersion(Engine_Obj *engine, NODE_Uuid uuid);
+
+static Void rserverClose(RServer server);
+static Void rserverDetach(Engine_Handle engine);
+static RServer rserverOpen(Engine_Desc * desc, Bool * startedServer,
+    String procId);
+
+extern Bool ti_sdo_ce_Engine_initFromServer;
+extern Bool Server_holdingTraceToken;
+
+/* REMEMBER: if you add an initialized static var, reinitialize it at cleanup */
+static Bool curInit = FALSE;
+
+/* The size of this table is numProcs - it's allocated/freed at runtime */
+static RServerObj *serverTab = NULL;
+
+static Queue_Elem stubFxnsList;
+
+/* set by CERuntime.xdt, determines if to collect DSP trace and how to set it */
+Bool   Engine_alwaysCollectDspTrace = FALSE;
+String Engine_ceDebugDspTraceMask   = "";
+
+static GateThread_Handle serverLock = NULL; /* serialize access to serverTab */
+static GateThread_Handle traceLock  = NULL;  /* serialize collectDspTrace */
+static GateThread_Handle engineLock = NULL; /* serialize rest of Engine */
+
+static Engine_Handle localEngine = NULL;
+static Queue_Elem engineList;
+
+static Int        numEngines = 0;
+static Queue_Elem engineDescList;
+
+/*
+ *  ======== collectDspTrace ========
+ */
+static Void collectDspTrace(Engine_Handle engine)
+{
+    IArg key;
+    Char prefix[32];   /* big enough? */
+
+    sprintf(prefix, "[%s] ", engine->procId);
+
+    key = GateThread_enter(traceLock);
+    Engine_fwriteTrace( engine, prefix, stdout );
+    GateThread_leave(traceLock, key);
+}
+
+/*
+ *  ======== Engine_add ========
+ */
+Engine_Error Engine_add(Engine_Desc *pDesc)
+{
+    Engine_Error    status = Engine_EOK;
+
+    Log_print1(Diags_ENTRY, "[+E] Engine_add(0x%x)", (IArg)pDesc);
+
+    if ((pDesc == NULL) || (pDesc->name == NULL)) {
+        Log_print0(Diags_USER7,
+                "[+7] Engine_add> Engine desc or desc->name is NULL!");
+        status = Engine_EINVAL;
+    }
+
+    if (status == Engine_EOK) {
+        /* Make sure engine name is not in already being used. */
+        if (getDescListElem(pDesc->name) != NULL) {
+            Log_print1(Diags_USER6, "[+6] Engine_add> Engine %s "
+                    "already exists!", (IArg)pDesc->name);
+            status = Engine_EINUSE;
+        }
+        else {
+            status = addEngineToList(pDesc, FALSE);
+        }
+    }
+
+    Log_print1(Diags_EXIT, "[+X] Engine_add> return (%d)", status);
+
+    return (status);
+}
+
+/*
+ *  ======== Engine_addAlg ========
+ */
+Engine_Error Engine_addAlg(String engName, Engine_Handle engine,
+        String location, Engine_AlgDesc *pAlgDesc)
+{
+    Engine_DescListElem    *descElem;
+    Engine_DllAlgDesc       dllAlgDesc;
+    Engine_AlgDesc          algDesc;
+    Loader_Handle           lib = NULL;
+    Engine_GetAlgDescFxn    getAlgDescFxn = NULL;
+    String                  libPath = NULL;
+    IArg                    key;
+    Engine_Error            status = Engine_EOK;
+
+
+    Log_print4(Diags_ENTRY, "[+E] Engine_addAlg('%s', 0x%lx, '%s', 0x%lx)",
+            (IArg)engName, (IArg)engine, (IArg)location, (IArg)pAlgDesc);
+
+    /* Exactly one of engName and engine must be non-NULL */
+    if ((!engine && !engName) || (engine && engName)) {
+        Log_print2(Diags_USER7, "[+7] Engine_addAlg> engine name = '%s', "
+                "engine handle = 0x%lx. Bad input args: One and only one of "
+                "these must be non-NULL!", (IArg)engName, (IArg)engine);
+        return (Engine_EINVAL);
+    }
+
+    /* Check pAlgDesc and fields */
+    if ((pAlgDesc == NULL) || (pAlgDesc->name == NULL)) {
+        Log_print1(Diags_USER7, "[+7] Engine_addAlg> Engine_AlgDesc [0x%x] "
+                "must be non-NULL, and must have a non-NULL alg name.",
+                (IArg)pAlgDesc);
+        return (Engine_EINVAL);
+    }
+
+    Engine_initAlgDesc(&algDesc);
+
+    if (location == NULL) {
+        /* Not a dynamic library, check more pAlgDesc params */
+        if (pAlgDesc->fxns == NULL) {
+            Log_print0(Diags_USER7, "[+7] Engine_addAlg> Engine_AlgDesc  "
+                    "fxns must not be NULL.");
+            return (Engine_EINVAL);
+        }
+
+        /*
+         *  TODO:
+         *  Older CERuntime macro, CE_LOCAL_ALG, for creating Engine_AlgDesc
+         *  uses typeTab array. If we can discontinue support of this macro,
+         *  we can just check 'types'.
+         */
+        if (((pAlgDesc->typeTab == NULL) || (pAlgDesc->typeTab[0] == NULL)) &&
+             (pAlgDesc->types == NULL)) {
+            Log_print0(Diags_USER7, "[+7] Engine_addAlg> Engine_AlgDesc  "
+                    "types must not be NULL.");
+            return (Engine_EINVAL);
+        }
+    }
+
+    Log_print3(Diags_ENTRY, "[+E] Engine_addAlg: alg params: name = %s, "
+            "isLocal = %d, groupId = %d",
+            (IArg)(pAlgDesc->name), (IArg)(pAlgDesc->isLocal),
+            (IArg)(pAlgDesc->groupId));
+
+    /* Only adding local algs is supported. Use Server_addAlg() for remote */
+    if (!pAlgDesc->isLocal) {
+        Log_print0(Diags_USER6,
+                "[+6] Engine_addAlg> Remote algs not supported. Use "
+                   "Server_addAlg() for adding remote algs.");
+        return (Engine_ENOTAVAIL);
+    }
+
+    key = GateThread_enter(engineLock);
+
+    /* Check if the engine already has an alg named pAlgDesc->name. */
+    if ((getAlgDesc(engName, engine, pAlgDesc->name)) != NULL) {
+        // TODO: Should we check that desc matches the one passed in
+        // and bump a reference count?
+        Log_print1(Diags_USER6, "[+6] Engine_addAlg> Name %s already in use "
+                "by an alg", (IArg)pAlgDesc->name);
+
+        GateThread_leave(engineLock, key);
+        return (Engine_EINUSE);
+    }
+
+    /*
+     *  If an engine name was passed in, make sure it exists and is not
+     *  in the "open" state.
+     */
+    if (engName) {
+        if ((descElem = getDescListElem(engName)) == NULL) {
+            Log_print1(Diags_USER7, "[+7] Engine_addAlg> Engine %s not found.",
+                    (IArg)engName);
+
+            GateThread_leave(engineLock, key);
+            return (Engine_EEXIST);
+        }
+
+        if (descElem->refCount) {
+            Log_print1(Diags_USER7, "[+7] Engine_addAlg> Engine %s is open. "
+                    "Cannot add alg using engine name, use engine handle "
+                    "instead.", (IArg)engName);
+            GateThread_leave(engineLock, key);
+            return (Engine_EINUSE);
+        }
+    }
+
+    if (location != NULL) {
+        /* Load the library containing the algs to add */
+        if ((libPath = Global_getenv("CE_LIBPATH")) != NULL) {
+            Loader_setSearchPath(libPath);
+        }
+
+        lib = Loader_loadLibrary(location);
+
+        if (lib == NULL) {
+            Log_print1(Diags_USER7, "[+7] Engine_addAlg-> "
+                    "Loader_loadLibrary() [%s] failed", (IArg)location);
+
+            /*
+             *  Unfortunately, there's no Engine_EFAIL we can return here. We
+             *  don't really no why the load failed. It could be that the
+             *  library was not in the correct format, or that it was not
+             *  found.  The Loader_loadLibrary() trace should indicate the
+             *  reason.
+             */
+            GateThread_leave(engineLock, key);
+            return (Engine_ENOTFOUND);
+        }
+        else {
+            Log_print0(Diags_USER1, "[+1] Engine_addAlg> loaded library.");
+        }
+
+        if (status == Engine_EOK) {
+            /* Get address of the function that fills in the alg descriptor. */
+            getAlgDescFxn = (Engine_GetAlgDescFxn)Loader_getSymbol(lib,
+                    Engine_GETALGDESCFXN);
+
+            if (getAlgDescFxn == NULL) {
+                Log_print1(Diags_USER7, "[+7] Engine_addAlg> "
+                        "Loader_getSymbol(): %s failed", (IArg)GETALGDESCFXN);
+
+                status = Engine_ENOTFOUND; // TODO: Add Engine_ESYMBOL?
+            }
+        }
+    }
+
+    if (status == Engine_EOK) {
+        algDesc = *pAlgDesc;
+
+        /* Fill in a new alg descriptor with info from DLL */
+        if (lib) {
+            /* groupId and isLocal are not known by dynamic library */
+            algDesc.groupId = pAlgDesc->groupId;
+            algDesc.isLocal = pAlgDesc->isLocal;
+
+            /* This may be unnecessary */
+
+            /* Get the rest of the alg descriptor from the library */
+            (*getAlgDescFxn)(&dllAlgDesc);
+
+            algDesc.fxns = dllAlgDesc.fxns;
+            algDesc.idmaFxns = dllAlgDesc.idmaFxns;
+            algDesc.iresFxns = dllAlgDesc.iresFxns;
+            algDesc.types = dllAlgDesc.types;
+        }
+        else {
+            algDesc.types = (pAlgDesc->types) ? pAlgDesc->types :
+                pAlgDesc->typeTab[0]; /* For CERuntime macros */
+        }
+
+        status = addAlg(engName, engine, &algDesc, lib);
+    }
+
+    if (status != Engine_EOK) {
+        /* Clean up */
+        if (lib) {
+            Loader_unloadLibrary(lib);
+        }
+    }
+
+    GateThread_leave(engineLock, key);
+    return (status);
+}
+
+/*
+ *  ======== Engine_addAlgRemote ========
+ *  Internal function. Called by Server_addAlg() to dynamically add an alg
+ *  to a remote server.
+ */
+Engine_Error Engine_addAlgRemote(Engine_Handle engine, String location,
+        Engine_AlgDesc *pAlgDesc, Engine_AlgRemoteDesc *pRemoteDesc)
+{
+    RMS_RmsMsg       *msg;
+    IArg              key;
+    Char             *buf;
+    Engine_AlgDesc    desc;
+    String            stubFxnsName = NULL;
+    IALG_Fxns         *stubFxns = NULL;
+    SKEL_Fxns         *skelFxns = NULL;
+    String            types;
+    Engine_Error      status = Engine_EOK;
+
+    Log_print3(Diags_ENTRY, "[+E] Engine_addAlgRemote(0x%lx, '%s', 0x%lx)",
+            (IArg)engine, (IArg)location, (IArg)pAlgDesc);
+
+    Assert_isTrue(engine != NULL, (Assert_Id)NULL);
+    Assert_isTrue(pRemoteDesc != NULL, (Assert_Id)NULL);
+
+    /*
+     *  Initialize an alg descriptor that will be filled in with values
+     *  from pRemoteDesc and pAlgDesc (for testing) or from a DLL.  Values
+     *  from this descriptor will then be used to fill in the RMS message.
+     */
+    Engine_initAlgDesc(&desc);
+
+    /* Check input parameters */
+    if (location == NULL) {
+        /*
+         *  Not loading a DLL, get params from pRemoteDesc. This case is
+         *  used for testing adding algs to remote server.
+         */
+        stubFxnsName = pRemoteDesc->stubFxnsName;
+        Assert_isTrue(stubFxnsName != NULL, (Assert_Id)NULL);
+
+        if (pRemoteDesc->skelFxns == NULL) {
+            Log_print0(Diags_USER7, "Engine_addAlgRemote> must specify "
+                    "skelFxns if not loading from DLL.");
+            return (Engine_EINVAL);
+        }
+
+        skelFxns = pRemoteDesc->skelFxns;
+
+        desc.fxns = pAlgDesc->fxns;
+        desc.iresFxns = pAlgDesc->iresFxns;
+        desc.idmaFxns = pAlgDesc->idmaFxns;
+        types = pAlgDesc->types;
+    }
+    else {
+        /*
+         *  Get stubFxnsName, skelFxns, fxns, idmaFxns, iresFxns,
+         *  types from DLL.
+         *  Currently not supported.
+         */
+        Log_print0(Diags_USER6,
+                "[+6] Engine_addAlgRemote> Adding remote from a DLL is "
+                "currently not supported.");
+        return (Engine_ENOTAVAIL);
+    }
+
+    if ((stubFxns = getStubFxns(stubFxnsName)) == NULL) {
+        Log_print1(Diags_USER7, "[+7] Engine_addAlgRemote> "
+                "Could not find stubFxns for %s in table! Please use "
+                "Engine_addStubFxns() to register these functions",
+                (IArg)stubFxnsName);
+        return (Engine_EINVAL);
+    }
+
+    key = GateThread_enter(engineLock);
+
+    /* Check if the engine already has an alg named pAlgDesc->name. */
+    if ((getAlgDesc(NULL, engine, pAlgDesc->name)) != NULL) {
+        // TODO: Should we check that desc matches the one passed in
+        // and bump a reference count?
+        Log_print1(Diags_USER6, "[+6] Engine_addAlgRemote> Name %s already "
+                "in use by an alg", (IArg)pAlgDesc->name);
+
+        GateThread_leave(engineLock, key);
+        return (Engine_EINUSE);
+    }
+
+    if ((msg = (RMS_RmsMsg *)engine->rmsMsg) == NULL) {
+        Log_print0(Diags_USER6,
+                "[+6] Engine_addAlgRemote> internal error: rms message null");
+        GateThread_leave(engineLock, key);
+        return (Engine_ERUNTIME);
+    }
+
+    msg->cmdBuf.cmd = RMS_ADDALG;
+    msg->cmdBuf.status = RMS_EFAIL;
+
+    /* Copy the alg name to the message buffer */
+    buf = (Char *)(msg->cmdBuf.data.addAlgIn.name);
+    strncpy(buf, pAlgDesc->name, RMS_MAXSTRLEN);
+    buf[RMS_MAXSTRLEN - 1] = '\0';
+
+    /* Copy the alg stub functions name */
+    buf = (Char *)(msg->cmdBuf.data.addAlgIn.stubFxnsName);
+    strncpy(buf, stubFxnsName, RMS_MAXSTRLEN);
+    buf[RMS_MAXSTRLEN - 1] = '\0';
+
+    /* Copy alg type inheritence string (Should come from DLL, eventually) */
+    buf = (Char *)(msg->cmdBuf.data.addAlgIn.typeTab);
+    strncpy(buf, pAlgDesc->types, RMS_MAXSTRLEN);
+    buf[RMS_MAXSTRLEN - 1] = '\0';
+
+    /*
+     *  These would normally come from a DLL, but we use pRemoteDesc as
+     *  a way to supply these values without loading and parsing the DLL.
+     */
+    msg->cmdBuf.data.addAlgIn.skelFxns = (RMS_Word)skelFxns;
+    msg->cmdBuf.data.addAlgIn.fxns = (RMS_Word)desc.fxns;
+    msg->cmdBuf.data.addAlgIn.idmaFxns = (RMS_Word)desc.idmaFxns;
+    msg->cmdBuf.data.addAlgIn.iresFxns = (RMS_Word)desc.iresFxns;
+
+    /* TODO: Should this come from the DLL? */
+    msg->cmdBuf.data.addAlgIn.codecClassConfig =
+        (RMS_Word)pRemoteDesc->codecClassConfig;
+
+    /* TODO: Should this come from the DLL? */
+    msg->cmdBuf.data.addAlgIn.memType = (RMS_Word)pAlgDesc->memType;
+
+    msg->cmdBuf.data.addAlgIn.groupId = (RMS_Word)pAlgDesc->groupId;
+    msg->cmdBuf.data.addAlgIn.priority = (RMS_Word)pRemoteDesc->priority;
+    msg->cmdBuf.data.addAlgIn.stackSize = (RMS_Word)pRemoteDesc->stackSize;
+    msg->cmdBuf.data.addAlgIn.stackSeg = (RMS_Word)pRemoteDesc->stackSeg;
+
+    Log_print1(Diags_USER2, "[+2] Engine_addAlgRemote> Sending RMS_ADDALG "
+            "command for alg %s", (IArg)pAlgDesc->name);
+
+    callServer(engine, (Comm_Msg *)&msg);
+
+    engine->rmsMsg = (Comm_Msg)msg;
+
+    /* check that remote cmd succeeded */
+    if (msg->cmdBuf.status != RMS_EOK) {
+        /* Index is out of range (shouldn't happen), we're done. */
+        Log_print2(Diags_USER7, "[+7] Engine_addAlgRemote> Could not add "
+                "alg [%s] to remote server.  Server error status: [%d]",
+                (IArg)pAlgDesc->name, (IArg)msg->cmdBuf.status);
+        status = Engine_ERUNTIME;
+        goto addAlgRemoteDone;
+    }
+
+    /* Now add the alg to the Engine's table of loaded algs */
+    Engine_initAlgDesc(&desc);
+
+    desc.fxns = stubFxns;
+    desc.idmaFxns = NULL;
+    desc.iresFxns = NULL;
+
+    /* Set the uuid to the value returned by the remote server. */
+    desc.uuid.data = msg->cmdBuf.data.addAlgOut.uuid.data;
+
+    Log_print2(Diags_USER2, "[+7] Engine_addAlgRemote> Alg %s, got uuid 0x%x",
+            (IArg)pAlgDesc->name, (IArg)desc.uuid.data);
+
+    /*
+     *  These strings will be copied in addAlg(), so no need to
+     *  allocate buffers for them here.
+     */
+    desc.name = pAlgDesc->name;
+    desc.types = types;  /* Could come from DLL */
+
+    desc.codecClassConfig = pAlgDesc->codecClassConfig;
+    desc.memType = pAlgDesc->memType;
+    desc.isLocal = FALSE;
+    desc.groupId = pAlgDesc->groupId;  /* Don't care about groupId here */
+
+    status = addAlg(NULL, engine, &desc, NULL);
+    if (status != Engine_EOK) {
+        /* TODO: Should we remove the alg from the server? */
+        Log_print1(Diags_USER7, "[+7] Engine_addAlgRemote> Engine_addAlg "
+                   "failed: %d", (IArg)status);
+    }
+
+addAlgRemoteDone:
+    GateThread_leave(engineLock, key);
+
+    return (status);
+}
+
+/*
+ *  ======== Engine_addStubFxns ========
+ */
+Engine_Error Engine_addStubFxns(String fxnsName, IALG_Fxns *fxns)
+{
+    Engine_StubFxnsElem *stubs;
+    Engine_Error         status = Engine_EOK;
+
+    Log_print2(Diags_ENTRY, "[+E] Engine_addStubFxns('%s', 0x%x)",
+            (IArg)fxnsName, (IArg)fxns);
+
+    stubs = Memory_alloc(sizeof(Engine_StubFxnsElem), NULL);
+
+    if (stubs == NULL) {
+        Log_print0(Diags_USER7, "[+7] Engine_addStubFxns> Memory allocation "
+                  "failed!");
+        status = Engine_ENOMEM;
+    }
+    else {
+        Queue_new(&stubs->link);
+
+        stubs->name = fxnsName;
+        stubs->stubFxns = fxns;
+
+        Queue_put(&stubFxnsList, stubs);
+    }
+
+    Log_print1(Diags_EXIT, "[+X] Engine_addStubFxns> return (%d)", status);
+    return (status);
+}
+
+/*
+ *  ======== Engine_removeAlg ========
+ */
+Engine_Error Engine_removeAlg(String engName, Engine_Handle engine,
+        String algName)
+{
+    _Engine_AlgLib    **loadedLibs = NULL;
+    Int                *numLoadedLibs;
+    _Engine_AlgLib     *curLib = NULL;
+    _Engine_AlgLib     *prevLib = NULL;
+    Engine_DescListElem *descElem = NULL;
+    IArg                key;
+    Engine_Error        status = Engine_ENOTFOUND;
+
+    Log_print3(Diags_ENTRY, "[+E] Engine_removeAlg('%s', 0x%lx, '%s')",
+            (IArg)engName, (IArg)engine, (IArg)algName);
+
+    if ((engName && engine) || (!engName && !engine)) {
+        Log_print2(Diags_USER7, "Engine_removeAlg> Bad input params: One of "
+                   "engine name [%s] and engine handle [0x%x] must be "
+                   "non-NULL, the other must be NULL",
+                (IArg)engName, (IArg)engine);
+        return (Engine_EINVAL);
+    }
+
+    if (algName == NULL) {
+        Log_print0(Diags_USER7, "Engine_removeAlg> Bad input params: alg "
+                "name must not be NULL");
+        return (Engine_EINVAL);
+    }
+
+    /* Lock list of engines */
+    key = GateThread_enter(engineLock);
+
+    if (engName != NULL) {
+        if ((descElem = getDescListElem(engName)) == NULL) {
+            Log_print1(Diags_USER7, "[+7] Engine_removeAlg> Engine %s "
+                    "not found.", (IArg)engName);
+
+            /* Release lock */
+            GateThread_leave(engineLock, key);
+            return (Engine_EEXIST);
+        }
+
+        /* Remove from list of algs added before engine was opened. */
+        loadedLibs = &(descElem->loadedLibs);
+        numLoadedLibs = &(descElem->numLoadedLibs);
+        curLib = descElem->loadedLibs;
+    }
+    else {
+        /*
+         *  Use list of algs added after the engine was opened. The engine
+         *  is obviously opened, so we can only remove from this list.
+         */
+        descElem = engine->descElem;
+        loadedLibs = &(engine->loadedLibs);
+        numLoadedLibs = &(engine->numLoadedLibs);
+        curLib = engine->loadedLibs;
+    }
+
+    prevLib = NULL;
+    while ((curLib != NULL)) {
+        if (strcmp(algName, curLib->algDesc.name) == 0) {
+            status = Engine_EOK;
+            break;
+        }
+        prevLib = curLib;
+        curLib = curLib->next;
+    }
+
+    if (curLib && engName && descElem->refCount) {
+        /*
+         *  Alg found in pre-opened list, but the engine has been opened.
+         *  We can't remove it because another thread may be using it.
+         */
+        Log_print1(Diags_USER7, "[+7] Engine_removeAlg> Engine %s is "
+                "open. Cannot remove alg that was added before engine was "
+                "opened.", (IArg)descElem->desc.name);
+        status = Engine_EINUSE;
+    }
+
+    if (status == Engine_EOK) {
+        Assert_isTrue(curLib != NULL, (Assert_Id)NULL);
+
+        /* Unlink the library from the list and free resources */
+        if (prevLib) {
+            prevLib->next = curLib->next;
+        }
+        else {
+            /* Removing the first in the list */
+            *loadedLibs = curLib->next;
+        }
+        (*numLoadedLibs)--;
+
+        if (curLib->lib) {
+            Loader_unloadLibrary(curLib->lib);
+        }
+
+        if (curLib->algDesc.name) {
+            Memory_free(curLib->algDesc.name, strlen(curLib->algDesc.name) + 1,
+                    NULL);
+        }
+
+        if (curLib->algDesc.types) {
+            Memory_free(curLib->algDesc.types,
+                    strlen(curLib->algDesc.types) + 1, NULL);
+        }
+
+        Algorithm_removeGroup(curLib->algDesc.groupId);
+
+        Memory_free(curLib, sizeof(_Engine_AlgLib), NULL);
+    }
+
+    /* Release lock */
+    GateThread_leave(engineLock, key);
+
+    Log_print1(Diags_EXIT, "[+X] Engine_removeAlg> return (%d)", status);
+    return (status);
+}
+
+/*
+ *  ======== Engine_call ========
+ */
+Int Engine_call(Engine_Node node, Comm_Msg *msg)
+{
+    Int status;
+
+    /* ensure that the node simply passes message to exec/call fxn */
+    NODE_Msg nodeMsg = (NODE_Msg)*msg;
+    nodeMsg->cmd.id = NODE_CCALL;
+
+    /* send the message */
+    Comm_setReplyToHandle(*msg, node->stdOut);
+    status = Comm_put(node->stdIn, *msg);
+
+    /* wait for the return message with the processed result */
+    if (status == Comm_EOK) {
+        status = Comm_get(node->stdOut, msg, Comm_FOREVER);
+    }
+
+    if (Engine_alwaysCollectDspTrace) {
+        collectDspTrace( node->engine );
+    }
+
+    return (status);
+}
+
+/*
+ *  ======== Engine_callAsync ========
+ */
+Int Engine_callAsync(Engine_Node node, Comm_Msg *msg)
+{
+    Int status;
+
+    /* ensure that the node simply passes message to exec/call fxn */
+    NODE_Msg nodeMsg = (NODE_Msg)*msg;
+    nodeMsg->cmd.id = NODE_CCALL;
+
+    /* send the message */
+    Comm_setReplyToHandle(*msg, node->stdOut);
+    status = Comm_put(node->stdIn, *msg);
+
+    if (Engine_alwaysCollectDspTrace) {
+        collectDspTrace( node->engine );
+    }
+
+    /* return w/o waiting for the return message with the processed result */
+    return (status);
+}
+
+/*
+ *  ======== Engine_callWait ========
+ */
+Int Engine_callWait(Engine_Node node, Comm_Msg *msg, UInt timeout)
+{
+    Int status;
+
+    status = Comm_get(node->stdOut, msg, timeout);
+
+    if (status != Comm_ETIMEOUT && Engine_alwaysCollectDspTrace) {
+        collectDspTrace( node->engine );
+    }
+
+    return (status);
+}
+
+/*
+ *  ======== Engine_remove ========
+ */
+Engine_Error Engine_remove(String engineName)
+{
+    Engine_DescListElem *descElem = NULL;
+    Engine_Desc         *desc = NULL;
+    IArg                 key;
+    Engine_Error         status = Engine_EOK;
+
+    Log_print1(Diags_ENTRY, "[+E] Engine_remove(%s)", (IArg)engineName);
+
+    key = GateThread_enter(engineLock);
+
+    descElem = getDescListElem(engineName);
+
+    if (descElem == NULL) {
+        Log_print0(Diags_USER6, "[+6] Engine_remove> engineName not found!");
+
+        GateThread_leave(engineLock, key);
+        return (Engine_EEXIST);
+    }
+
+    if (descElem->isStatic) {
+        Log_print0(Diags_USER2, "[+2] Engine_remove> Can't remove "
+                "pre-configured engine");
+
+        GateThread_leave(engineLock, key);
+        return (Engine_EEXIST);
+    }
+
+    Log_print1(Diags_USER4, "[+4] Engine_remove> engine refCount[%d]\n",
+            descElem->refCount);
+
+    if (descElem->refCount != 0) {
+        Log_print1(Diags_USER6, "[+6] Engine_remove> engine refCount[%d] != 0",
+                descElem->refCount);
+
+        GateThread_leave(engineLock, key);
+        return (Engine_EINUSE);
+    }
+
+    /* Remove desc from the list and free */
+    Queue_extract((Queue_Elem *)descElem);
+
+    numEngines--;
+    GateThread_leave(engineLock, key);
+
+    /* Only free names from dynamically added engines */
+    Assert_isTrue(descElem->isStatic == FALSE, (Assert_Id)NULL);
+    desc = &descElem->desc;
+    if (desc->name) {
+        Memory_free(desc->name, strlen(desc->name) + 1, NULL);
+    }
+    if (desc->remoteName) {
+        Memory_free(desc->remoteName, strlen(desc->remoteName) + 1, NULL);
+    }
+    if (desc->memMap) {
+        Memory_free(desc->memMap, strlen(desc->memMap) + 1, NULL);
+    }
+
+    Memory_free(descElem, sizeof(Engine_DescListElem), NULL);
+
+    Log_print1(Diags_EXIT, "[+X] Engine_remove> returning %d", status);
+    return (status);
+}
+
+/*
+ *  ======== Engine_getDesc ========
+ */
+Engine_Error Engine_getDesc(String name, Engine_Desc *desc)
+{
+    Engine_DescListElem *descElem;
+    IArg                 key;
+    Engine_Error         status = Engine_EOK;
+
+    if ((name == NULL) || (desc == NULL)) {
+        Log_print0(Diags_USER7, "[+7] Engine_getDesc> NULL input parameter");
+        return (Engine_EINVAL);
+    }
+
+    key = GateThread_enter(engineLock);
+
+    if ((descElem = getDescListElem(name)) == NULL) {
+        Log_print1(Diags_USER7, "[+7] Engine_getDesc> Engine %s not found.",
+                (IArg)name);
+
+        GateThread_leave(engineLock, key);
+        return (Engine_EEXIST);
+    }
+
+    *desc = descElem->desc;
+
+    GateThread_leave(engineLock, key);
+
+    return (status);
+}
+
+/*
+ *  ======== Engine_setDesc ========
+ */
+Engine_Error Engine_setDesc(String name, Engine_Desc *desc)
+{
+    Engine_DescListElem *descElem;
+    IArg                 key;
+    Engine_Error         status = Engine_EOK;
+
+
+    if ((name == NULL) || (desc == NULL)) {
+        Log_print0(Diags_USER7, "[+7] Engine_setDesc> NULL input parameter");
+        return (Engine_EINVAL);
+    }
+
+    key = GateThread_enter(engineLock);
+
+    if ((descElem = getDescListElem(name)) == NULL) {
+        Log_print1(Diags_USER7, "[+7] Engine_setDesc> Engine %s not found.",
+                (IArg)name);
+
+        GateThread_leave(engineLock, key);
+        return (Engine_EEXIST);
+    }
+
+    if (descElem->refCount) {
+        Log_print1(Diags_USER7, "[+7] Engine_setDesc> Engine %s is open. "
+                "Cannot change the descriptor.", (IArg)name);
+        GateThread_leave(engineLock, key);
+        return (Engine_EINUSE);
+    }
+
+    /* Copy the fields that are allowed to be changed. */
+    descElem->desc.memMap = desc->memMap;
+    descElem->desc.useExtLoader = desc->useExtLoader;
+    descElem->desc.heapId = desc->heapId;
+
+    GateThread_leave(engineLock, key);
+
+    return (status);
+}
+
+/*
+ *  ======== Engine_getMemStat ========
+ */
+Engine_Error Engine_getMemStat(Server_Handle server, Int segNum,
+    Engine_MemStat *stat)
+{
+    Engine_Handle    engine = (Engine_Handle)server;
+    RMS_RmsMsg      *msg;
+    Engine_Error     status = Engine_EOK;
+
+    Log_print3(Diags_ENTRY, "[+E] Engine_getMemStat(0x%lx, %d, 0x%lx)",
+            (IArg)engine, (IArg)segNum, (IArg)stat);
+
+    if (engine->hasServer != TRUE) {
+        return (Engine_ENOSERVER);
+    }
+
+    if ((msg = (RMS_RmsMsg *)engine->rmsMsg) == NULL) {
+        Log_print0(Diags_USER6,
+                "[+6] Engine_getMemStat> internal error: rms message null");
+        return (Engine_ERUNTIME);
+    }
+
+    /* Set up command */
+    msg->cmdBuf.cmd = RMS_GETSEGSTAT;
+    msg->cmdBuf.status = RMS_EFAIL;
+    msg->cmdBuf.data.getSegStatIn.segId = segNum;
+
+    callServer(engine, (Comm_Msg *)&msg);
+
+    engine->rmsMsg = (Comm_Msg)msg;
+
+    /* check that remote cmd succeeded */
+    if (msg->cmdBuf.status == RMS_ENOTFOUND) {
+        /* segNum is out of range. */
+        status = engine->lastError = Engine_ENOTFOUND;
+    }
+    else if (msg->cmdBuf.status != RMS_EOK) {
+        status = engine->lastError = Engine_ERUNTIME;
+    }
+    else {
+        /* Copy data into stat */
+        strncpy(stat->name, (Char *)msg->cmdBuf.data.getSegStatOut.name,
+                Engine_MAXSEGNAMELENGTH);
+        stat->name[Engine_MAXSEGNAMELENGTH] = '\0';
+        stat->base = msg->cmdBuf.data.getSegStatOut.base;
+        stat->size = msg->cmdBuf.data.getSegStatOut.size;
+        stat->used = msg->cmdBuf.data.getSegStatOut.used;
+        stat->maxBlockLen = msg->cmdBuf.data.getSegStatOut.maxBlockLen;
+    }
+
+    return (status);
+}
+
+/*
+ *  ======== Engine_getNumServerAlgs ========
+ */
+Engine_Error Engine_getNumServerAlgs(Server_Handle server, Int *nAlgs)
+{
+    Engine_Handle    engine = (Engine_Handle)server;
+    RMS_RmsMsg      *msg;
+    Engine_Error     status = Engine_EOK;
+
+    Log_print2(Diags_ENTRY, "[+E] Engine_getNumServerAlgs(0x%lx 0x%lx)",
+            (IArg)engine, (IArg)nAlgs);
+
+    if (engine->hasServer != TRUE) {
+        Log_print0(Diags_USER6,
+            "[+6] Engine_getNumServerAlgs> Engine does not have a server");
+        return (Engine_ENOSERVER);
+    }
+
+    if ((msg = (RMS_RmsMsg *)engine->rmsMsg) == NULL) {
+        Log_print0(Diags_USER6, "[+6] Engine_getNumServerAlgs> "
+                "internal error: rms message null");
+        return (Engine_ERUNTIME);
+    }
+
+    /* copy command */
+    msg->cmdBuf.cmd = RMS_GETNUMALGS;
+    msg->cmdBuf.status = RMS_EFAIL;
+
+    callServer(engine, (Comm_Msg *)&msg);
+
+    engine->rmsMsg = (Comm_Msg)msg;
+
+    /* check that remote cmd succeeded */
+    if (msg->cmdBuf.status != RMS_EOK) {
+        engine->lastError = Engine_ERUNTIME;
+        status = Engine_ERUNTIME;
+    }
+    else {
+        *nAlgs = msg->cmdBuf.data.getNumAlgsOut.numAlgs;
+    }
+
+    Log_print1(Diags_USER2, "[+2] Engine_getNumServerAlgs> number of server "
+            "algs = %d", *nAlgs);
+
+    Log_print1(Diags_EXIT, "[+X] Engine_getNumServerAlgs> Returning %d",
+            (IArg)status);
+    return (status);
+}
+
+/*
+ *  ======== Engine_getNumMemSegs ========
+ */
+Engine_Error Engine_getNumMemSegs(Server_Handle server, Int *numSegs)
+{
+    Engine_Handle    engine = (Engine_Handle)server;
+    RMS_RmsMsg      *msg;
+    Engine_Error     status = Engine_EOK;
+
+    Log_print2(Diags_ENTRY, "[+E] Engine_getNumMemSegs(0x%lx 0x%lx)",
+            (IArg)engine, (IArg)numSegs);
+
+    if (engine->hasServer != TRUE) {
+        return (Engine_ENOSERVER);
+    }
+
+    if ((msg = (RMS_RmsMsg *)engine->rmsMsg) == NULL) {
+        Log_print0(Diags_USER6,
+                "[+6] Engine_getNumMemSegs> internal error: rms message null");
+        return (Engine_ERUNTIME);
+    }
+
+    /* copy command */
+    msg->cmdBuf.cmd = RMS_GETNUMSEGS;
+    msg->cmdBuf.status = RMS_EFAIL;
+
+    callServer(engine, (Comm_Msg *)&msg);
+
+    engine->rmsMsg = (Comm_Msg)msg;
+
+    /* check that remote cmd succeeded */
+    if (msg->cmdBuf.status != RMS_EOK) {
+        engine->lastError = Engine_ERUNTIME;
+        status = Engine_ERUNTIME;
+    }
+    else {
+        *numSegs = msg->cmdBuf.data.getNumSegsOut.numSegs;
+    }
+
+    return (status);
+}
+
+/*
+ *  ======== Engine_close ========
+ */
+Void Engine_close(Engine_Handle engine)
+{
+    _Engine_AlgLib *curLib;
+    IArg            key;
+    IArg            keyServerLock;
+
+    Log_print1(Diags_ENTRY, "[+E] Engine_close(0x%lx)", (IArg)engine);
+
+    if (engine != NULL) {
+
+        if (Engine_alwaysCollectDspTrace) {
+            collectDspTrace(engine);
+        }
+
+        keyServerLock = GateThread_enter(serverLock);
+
+        if (engine->server != NULL) {
+            rserverDetach(engine);
+        }
+
+        /* atomically remove engine from any list it may be on */
+        Queue_extract(&engine->link);
+
+        if (engine->rmsMsg != NULL) {
+            Comm_free(engine->rmsMsg);
+        }
+
+        if (engine->fromRMS != NULL) {
+            Comm_delete(engine->fromRMS);
+        }
+
+        if (engine->toRMS != Comm_INVALIDMSGQ) {
+            Comm_release(engine->toRMS);
+        }
+
+        if (engine->server != NULL) {
+            rserverClose(engine->server);
+        }
+
+        GateThread_leave(serverLock, keyServerLock);
+
+
+        /* Clean up any dynamically loaded algs */
+        while ((curLib = engine->loadedLibs) != NULL) {
+            Engine_removeAlg(NULL, engine, curLib->algDesc.name);
+        }
+
+        if (engine->remoteAlgTab != NULL) {
+            freeServerTab(engine);
+        }
+
+        /* Decrement count of number opened for this Engine descriptor */
+        key = GateThread_enter(engineLock);
+        engine->descElem->refCount--;
+        GateThread_leave(engineLock, key);
+
+        /* free Engine object */
+        Memory_free(engine, sizeof(Engine_Obj), NULL);
+    }
+}
+
+/*
+ *  ======== Engine_createNode ========
+ */
+Engine_Node Engine_createNode(Engine_Handle engine, String impId,
+    size_t msgSize, IALG_Params *nodeAttrs, Engine_AlgCreateAttrs *attrs)
+{
+    Int nodeAttrsSize;
+
+    Log_print5(Diags_ENTRY,
+            "[+E] Engine_createNode(0x%lx, '%s', %d, 0x%lx, 0x%lx)",
+            (IArg)engine, (IArg)impId, (IArg)msgSize, (IArg)nodeAttrs,
+            (IArg)attrs);
+
+    nodeAttrsSize = nodeAttrs ? nodeAttrs->size : 0;
+
+    return (Engine_createNode2(engine, impId, msgSize, nodeAttrs,
+                    nodeAttrsSize, attrs));
+}
+
+/*
+ *  ======== Engine_createNode2 ========
+ */
+Engine_Node Engine_createNode2(Engine_Handle engine, String impId,
+    size_t msgSize, IALG_Params *nodeAttrs, Int nodeAttrsSize,
+    Engine_AlgCreateAttrs *attrs)
+{
+    RMS_RmsMsg *msg;
+    Engine_Node node = NULL;
+
+    Log_print6(Diags_ENTRY,
+            "[+E] Engine_createNode(0x%lx, '%s', %d, 0x%lx, 0x%lx, 0x%lx)",
+            (IArg)engine, (IArg)impId, (IArg)msgSize, (IArg)nodeAttrs,
+            (IArg)nodeAttrsSize, (IArg)attrs);
+
+    if (attrs == NULL) {
+        attrs = &Engine_ALGCREATEATTRS;
+    }
+
+    if (nodeAttrsSize > (sizeof(RMS_Word) * RMS_MAXARGSLENGTH)) {
+        Log_print2(Diags_USER6,
+                "[+6] Engine_createNode> rms message size [%d] insufficient"
+                " for nodeAttrsSize [%d]",
+                (IArg)(sizeof(RMS_Word) * RMS_MAXARGSLENGTH),
+                (IArg)nodeAttrsSize);
+
+        engine->lastError = Engine_EINVAL;
+        goto createNodeEnd;
+    }
+
+    if ((msg = (RMS_RmsMsg *)engine->rmsMsg) == NULL) {
+        Log_print0(Diags_USER6,
+                "[+6] Engine_createNode> internal error: rms message null");
+
+        engine->lastError = Engine_ERUNTIME;
+        goto createNodeEnd;
+    }
+
+    if ((node = allocNode(engine, impId)) == NULL) {
+        Log_print0(Diags_USER6,
+                "[+6] Engine_createNode> Node allocation failed.");
+
+        /* engine->lastError is set in allocNode, don't override it */
+        goto createNodeEnd;
+    }
+
+    node->msgSize = msgSize;
+
+    /* init a "node create" message */
+    msg->cmdBuf.cmd = RMS_CREATENODE;
+    msg->cmdBuf.status = RMS_EFAIL;
+    name2Uuid(engine, impId, &msg->cmdBuf.data.createNodeIn.uuid);
+    msg->cmdBuf.data.createNodeIn.rpcProtocolVersion =
+        getRpcProtocolVersion(engine, msg->cmdBuf.data.createNodeIn.uuid);
+    msg->cmdBuf.data.createNodeIn.gppQueue = Comm_getId(node->stdOut);
+    msg->cmdBuf.data.createNodeIn.nodePriority = attrs->priority;
+    msg->cmdBuf.data.createNodeIn.useExtHeap = attrs->useExtHeap;
+
+    if (nodeAttrs == NULL) {
+        msg->cmdBuf.data.createNodeIn.argLength = 0;
+    }
+    else {
+        assert(nodeAttrsSize <= (sizeof (RMS_Word) * RMS_MAXARGSLENGTH));
+        msg->cmdBuf.data.createNodeIn.argLength = nodeAttrsSize;
+        memcpy(msg->cmdBuf.data.createNodeIn.argBuffer, nodeAttrs,
+                nodeAttrsSize);
+    }
+
+    /* send create message to RMS */
+    Comm_setReplyToHandle((Comm_Msg)msg, engine->fromRMS);
+    if (Comm_put(engine->toRMS, (Comm_Msg)msg) == Comm_EOK) {
+        Int status;
+        status = Comm_get(engine->fromRMS, (Comm_Msg *)&msg, Comm_FOREVER);
+        assert(status == Comm_EOK);
+        engine->rmsMsg = (Comm_Msg)msg;
+    }
+    else {
+        freeNode(node);
+        node = NULL;
+        Log_print0(Diags_USER6,
+                "[+6] Engine_createNode> FAILED to send creation msg to DSP.");
+
+        engine->lastError = Engine_ENOCOMM;
+        goto createNodeEnd;
+    }
+
+    /* check that remote create succeeded */
+    if (msg->cmdBuf.status != RMS_EOK) {
+        freeNode(node);
+        node = NULL;
+        Log_print1(Diags_USER6,
+                "[+6] Engine_createNode> Remote node creation FAILED (0x%x).",
+                (IArg)(msg->cmdBuf.status));
+        engine->lastError = Engine_ECODECCREATE;
+
+        goto createNodeEnd;
+    }
+
+    /* get the remote node and visa handles, and remote message queue */
+    node->rmsNode = msg->cmdBuf.data.createNodeOut.node;
+    node->remoteVisa = msg->cmdBuf.data.createNodeOut.remoteVisa;
+
+    /* we really should do a locate here!!! */
+    node->stdIn = msg->cmdBuf.data.createNodeOut.nodeQueue;
+
+    /* put start message to engine's RMS */
+    msg->cmdBuf.cmd = RMS_STARTNODE;
+    msg->cmdBuf.status = RMS_EFAIL;
+    msg->cmdBuf.data.startNodeIn.node = node->rmsNode;
+    Comm_setReplyToHandle((Comm_Msg)msg, engine->fromRMS);
+    if (Comm_put(engine->toRMS, (Comm_Msg)msg) == Comm_EOK) {
+        Int status;
+        status = Comm_get(engine->fromRMS, (Comm_Msg *)&msg, Comm_FOREVER);
+        assert(status == Comm_EOK);
+        engine->rmsMsg = (Comm_Msg)msg;
+    }
+
+    /* check that remote start succeeded */
+    if (msg->cmdBuf.status != RMS_EOK) {
+        freeNode(node);
+        node = NULL;
+        Log_print1(Diags_USER6,
+                "[+6] Engine_createNode> Remote start FAILED (0x%x).",
+                (IArg)(msg->cmdBuf.status));
+
+        engine->lastError = Engine_ECODECSTART;
+        goto createNodeEnd;
+    }
+
+    Log_print5(Diags_USER4, "[+4] Engine_createNode> created node"
+            "(stdIn=0x%x, stdOut=0x%x, algName='%s', rmsNode=0x%x, "
+            "algHandle=0x%x)",
+            (IArg)(node->stdIn), (IArg)(node->stdOut),
+            (IArg)(node->impId), (IArg)(node->rmsNode),
+            (IArg)(node->remoteVisa));
+    Log_print1(Diags_USER4, "[+4]   Comm_getId(node->stdOut)=0x%x",
+            (IArg)(Comm_getId(node->stdOut)));
+
+createNodeEnd:
+
+    if (Engine_alwaysCollectDspTrace) {
+        collectDspTrace( engine );
+    }
+
+    Log_print1(Diags_USER2, "[+2] Engine_createNode> Returning 0x%x",
+            (IArg)node);
+
+    return (node);
+}
+
+/*
+ *  ======== Engine_ctrlNode ========
+ */
+Int Engine_ctrlNode(Engine_Node node, Comm_Msg *msg, Engine_Ctrl code)
+{
+    Int status;
+    NODE_Msg nodeMsg = (NODE_Msg)*msg;
+
+    if (code != Engine_CEXIT) {
+        return (Engine_EINVAL);
+    }
+
+    nodeMsg->cmd.id = NODE_CEXIT;
+
+    /* send the message */
+    Comm_setReplyToHandle(*msg, node->stdOut);
+    status = Comm_put(node->stdIn, *msg);
+
+    /* wait for the return message with the processed result */
+    if (status == Comm_EOK) {
+        status = Comm_get(node->stdOut, msg, Comm_FOREVER);
+    }
+
+    return (status);
+}
+/*
+ *  ======== Engine_deleteNode ========
+ */
+Void Engine_deleteNode(Engine_Node node)
+{
+    Engine_Handle engine = node->engine;
+    RMS_RmsMsg *msg = (RMS_RmsMsg *)engine->rmsMsg;
+
+    Log_print1(Diags_ENTRY, "[+E] Engine_deleteNode(0x%lx)", (IArg)node);
+
+    /* init a node delete message */
+    msg->cmdBuf.cmd = RMS_DELETENODE;
+    msg->cmdBuf.data.deleteNodeIn.node = node->rmsNode;
+
+    /* put delete node message to engine's RMS */
+    Comm_setReplyToHandle((Comm_Msg)msg, engine->fromRMS);
+    if (Comm_put(engine->toRMS, (Comm_Msg)msg) == Comm_EOK) {
+        Int status;
+        status = Comm_get(engine->fromRMS, (Comm_Msg *)&msg, Comm_FOREVER);
+        if (status == Comm_EOK) {
+            /* check stack size to see if we are close to overrun */
+            Bits16 classMask = Diags_USER5;
+            UInt stacksize = msg->cmdBuf.data.deleteNodeOut.stackSize;
+            UInt stackused = msg->cmdBuf.data.deleteNodeOut.stackUsed;
+            Int headroom = 100;
+
+            if (stacksize != 0) {
+                headroom = (stacksize > stackused)
+                    ? ((stacksize - stackused) * 100) / stacksize : 0;
+            }
+
+            if (headroom < 10) {
+                classMask |= Diags_USER6; /* less than 10%, generate warning */
+            }
+            Log_print6(classMask, "Engine_deleteNode(0x%x): "
+                    "algName = %s, algHandle = 0x%x, stack size = %d, "
+                    "stack used = %d(%d%%)",
+                    (IArg)node, (IArg)(node->impId), (IArg)(node->remoteVisa),
+                    (IArg)stacksize, (IArg)stackused, (IArg)(100 - headroom));
+
+            engine->rmsMsg = (Comm_Msg)msg;
+        }
+    }
+
+    freeNode(node);
+}
+
+/*
+ *  ======== Engine_getAlgInfo ========
+ */
+Engine_Error Engine_getAlgInfo(String name, Engine_AlgInfo *algInfo, Int index)
+{
+    Engine_AlgDesc      *alg;
+    IArg                 key;
+    Engine_Error         status = Engine_EOK;
+
+    Log_print3(Diags_ENTRY, "[+E] Engine_getAlgInfo('%s', 0x%lx, 0x%x)",
+            (IArg)name, (IArg)algInfo, (IArg)index);
+
+    /* Check params */
+    if ((name == NULL) || (algInfo == NULL) || (index < 0)) {
+        return (Engine_EINVAL);
+    }
+
+    /* Make sure size matches with this library version's size */
+    if (algInfo->algInfoSize != sizeof(Engine_AlgInfo)) {
+        Log_print2(Diags_USER6,
+                "[+6] Engine_getAlgInfo(): Input Engine_AlgInfo struct size "
+                "[%d] does not match library Engine_AlgInfo struct size [%d]",
+                (IArg)(algInfo->algInfoSize), (IArg)(sizeof(Engine_AlgInfo)));
+        return (Engine_EINVAL);
+    }
+
+    /* Acquire lock to prevent algs from being added or removed */
+    key = GateThread_enter(engineLock);
+
+    alg = getAlgDescNum(name, NULL, index);
+
+    if (alg == NULL) {
+        Log_print2(Diags_USER6,
+                "[+6] Engine_getAlgInfo(): Engine [%s], alg number [%d]"
+                "not found.", (IArg)name, (IArg)index);
+        status = Engine_EINVAL;
+    }
+    else {
+        algInfo->name = alg->name;
+        algInfo->typeTab = alg->typeTab;
+        algInfo->isLocal = alg->isLocal;
+    }
+
+    GateThread_leave(engineLock, key);
+
+    return (status);
+}
+
+/*
+ *  ======== Engine_getAlgInfo2 ========
+ */
+Engine_Error Engine_getAlgInfo2(String name, Engine_Handle engine,
+        Engine_AlgInfo2 *algInfo2, Int index)
+{
+    Engine_AlgDesc      *alg;
+    IArg                 key;
+    Engine_Error         status = Engine_EOK;
+
+    Log_print4(Diags_ENTRY, "[+E] Engine_getAlgInfo2('%s' 0x%lx 0x%lx 0x%x)",
+            (IArg)name, (IArg)engine, (IArg)algInfo2, (IArg)index);
+
+    /* Check params */
+    if ((algInfo2 == NULL) || (index < 0)) {
+        Log_print2(Diags_USER7, "[+7] Engine_getAlgInfo2> Ensure that "
+                "paramaters algInfo2 [0x%lx] is non-NULL and index [%d] >= 0.",
+                (IArg)algInfo2, (IArg)index);
+        return (Engine_EINVAL);
+    }
+    if ((name && engine) || (!name && !engine)) {
+        Log_print2(Diags_USER7, "[+7] Engine_getAlgInfo2> engine name = '%s', "
+                "engine handle = 0x%lx. Bad input args: One and only one of "
+                "these must be non-NULL!", (IArg)name, (IArg)engine);
+        return (Engine_EINVAL);
+    }
+
+    /* Make sure size matches with this library version's size */
+    if (algInfo2->algInfoSize != sizeof(Engine_AlgInfo2)) {
+        Log_print2(Diags_USER6,
+            "[+6] Engine_getAlgInfo2(): Input Engine_AlgInfo2 struct size [%d]"
+            "does not match library Engine_AlgInfo2 struct size [%d]",
+            (IArg)algInfo2->algInfoSize, (IArg)sizeof(Engine_AlgInfo2));
+        return (Engine_EINVAL);
+    }
+
+    /* Acquire lock to prevent algs from being added or removed */
+    key = GateThread_enter(engineLock);
+
+    alg = getAlgDescNum(name, engine, index);
+
+    if (alg == NULL) {
+        Log_print2(Diags_USER6,
+                "[+6] Engine_getAlgInfo2(): Engine [%s], alg number [%d]"
+                "not found.", (IArg)name, (IArg)index);
+        status = Engine_EINVAL;
+    }
+    else {
+        algInfo2->name = alg->name;
+        algInfo2->isLocal = alg->isLocal;
+
+        /*
+         *  For auto-generated alg tables and algs obtained from the server,
+         *  alg->types will not be NULL. If alg table was not generated with
+         *  XDC tools (eg, for run-time config), this could be NULL. In that
+         *  case, just use typeTab[0], since that will contain the complete
+         *  inheritence hierarchy (assuming the it was configured correctly by
+         *  the app).
+         */
+        algInfo2->types = alg->types;
+    }
+
+    GateThread_leave(engineLock, key);
+
+    return (status);
+}
+
+
+/*
+ *  ======== Engine_getAlgMemRecs ========
+ */
+Engine_Error Engine_getAlgMemRecs(Engine_Node node, IALG_MemRec *memTab,
+        Int size, Int *numRecs)
+{
+    Engine_Handle    engine;
+    RMS_RmsMsg      *msg;
+    Int              nRecs;
+    Int              i;
+    IALG_MemRec     *memRecs;
+    Engine_Error     status = Engine_EOK;
+
+    Log_print4(Diags_ENTRY,
+            "[+E] Engine_getAlgMemRecs(0x%lx, 0x%x, %d, 0x%lx)",
+            (IArg)node, (IArg)memTab, (IArg)size, (IArg)numRecs);
+
+    engine = node->engine;
+    msg = (RMS_RmsMsg *)engine->rmsMsg;
+
+    /* Compute maximum number of IALG_MemRecs that can be copied. */
+    nRecs = (size > RMS_MAXMEMRECS) ? RMS_MAXMEMRECS : size;
+    if (size > nRecs) {
+        Log_print3(Diags_USER4,
+                "[+4] Engine_getAlgMemRecs: memTab array size (%d) is larger"
+                " then the number of records that can be copied (%d) for"
+                " node (0x%x)", (IArg)size, (IArg)RMS_MAXMEMRECS, (IArg)node);
+    }
+
+    /* Set up command */
+    msg->cmdBuf.cmd = RMS_GETMEMRECS;
+    msg->cmdBuf.status = RMS_EFAIL;
+    msg->cmdBuf.data.getMemRecsIn.node = node->rmsNode;
+    msg->cmdBuf.data.getMemRecsIn.numRecs = nRecs;
+
+    callServer(engine, (Comm_Msg *)&msg);
+
+    engine->rmsMsg = (Comm_Msg)msg;
+
+    /* check that remote cmd succeeded */
+    if (msg->cmdBuf.status != RMS_EOK) {
+        // TODO: Determine what type of errors will be returned.
+        if (msg->cmdBuf.status == RMS_EINVAL) {
+            status = engine->lastError = Engine_EINVAL;
+        }
+        else if (msg->cmdBuf.status == RMS_ENOTFOUND) {
+            status = engine->lastError = Engine_ENOTFOUND;
+        }
+        else {
+            status = engine->lastError = Engine_ERUNTIME;
+        }
+    }
+    else {
+        *numRecs = msg->cmdBuf.data.getMemRecsOut.numRecs;
+        memRecs = (IALG_MemRec *)(msg->cmdBuf.data.getMemRecsOut.memRecs);
+
+        for (i = 0; i < nRecs; i++) {
+            memTab[i] = memRecs[i];
+        }
+    }
+
+    Log_print1(Diags_EXIT, "[+X] Engine_getAlgMemRecs> Returning %d",
+            (IArg)status);
+
+    return (status);
+}
+
+/*
+ *  ======== Engine_getAlgNumRecs ========
+ */
+Engine_Error Engine_getAlgNumRecs(Engine_Node node, Int *numRecs)
+{
+    Engine_Handle    engine;
+    RMS_RmsMsg      *msg;
+    Engine_Error     status = Engine_EOK;
+
+    Log_print2(Diags_ENTRY, "[+E] Engine_getAlgNumRecs(0x%lx, 0x%x)",
+            (IArg)node, (IArg)numRecs);
+
+    engine = node->engine;
+    msg = (RMS_RmsMsg *)engine->rmsMsg;
+
+    /* Set up command */
+    msg->cmdBuf.cmd = RMS_GETNUMMEMRECS;
+    msg->cmdBuf.status = RMS_EFAIL;
+    msg->cmdBuf.data.getNumRecsIn.node = node->rmsNode;
+
+    callServer(engine, (Comm_Msg *)&msg);
+
+    engine->rmsMsg = (Comm_Msg)msg;
+
+    /* check that remote cmd succeeded */
+    if (msg->cmdBuf.status != RMS_EOK) {
+        // TODO: Determine what type of errors will be returned.
+        if (msg->cmdBuf.status == RMS_EINVAL) {
+            status = engine->lastError = Engine_EINVAL;
+        }
+        else if (msg->cmdBuf.status == RMS_ENOTFOUND) {
+            status = engine->lastError = Engine_ENOTFOUND;
+        }
+        else {
+            status = engine->lastError = Engine_ERUNTIME;
+        }
+    }
+    else {
+        *numRecs = msg->cmdBuf.data.getNumRecsOut.numRecs;
+    }
+
+    Log_print1(Diags_EXIT, "[+X] Engine_getAlgNumRecs> Returning %d",
+            (IArg)status);
+
+    return (status);
+}
+
+/*
+ *  ======== Engine_getNumAlgs ========
+ */
+Engine_Error Engine_getNumAlgs(String name, Int *numAlgs)
+{
+    Engine_DescListElem *descElem;
+
+    Log_print2(Diags_ENTRY, "[+E] Engine_getNumAlgs('%s', 0x%x)",
+            (IArg)name, (IArg)numAlgs);
+
+    *numAlgs = 0;
+
+    descElem = getDescListElem(name);
+    if (descElem == NULL) {
+        return (Engine_EEXIST);
+    }
+
+    /* Engine found - get number of algs */
+    *numAlgs = descElem->desc.numAlgs + descElem->numLoadedLibs;
+
+    Log_print2(Diags_EXIT, "[+X] Engine_getNumAlgs> Returning %d (0x%x algs)",
+            (IArg)Engine_EOK, (IArg)*numAlgs);
+    return (Engine_EOK);
+}
+
+/*
+ *  ======== Engine_getNumAlgs2 ========
+ */
+Engine_Error Engine_getNumAlgs2(String name, Engine_Handle engine, Int *nAlgs)
+{
+    Engine_Desc      *desc;
+
+    Log_print3(Diags_ENTRY, "[+E] Engine_getNumAlgs2('%s', 0x%lx, 0x%lx)",
+        (IArg)name, (IArg)engine, (IArg)nAlgs);
+
+    *nAlgs = 0;
+
+    if (engine == NULL) {
+        return (Engine_getNumAlgs(name, nAlgs));
+    }
+    else {
+        desc = engine->desc;
+
+        *nAlgs = desc->numAlgs + engine->numRemoteAlgs +
+            engine->descElem->numLoadedLibs + engine->numLoadedLibs;
+    }
+
+    return (Engine_EOK);
+}
+
+/*
+ *  ======== Engine_getConstName ========
+ */
+String Engine_getConstName(Engine_Handle engine, String name, String type)
+{
+    Engine_AlgDesc *alg;
+
+    if (engine == NULL) {
+        engine = Engine_getLocalEngine();
+    }
+
+    if ((alg = getAlgDesc(NULL, engine, name)) != NULL) {
+        if (isa(alg, type)) {
+            return (alg->name);
+        }
+    }
+
+    Log_print2(Diags_USER6,
+            "[+6] Engine_getConstName> Unable to locate alg \"%s\" (type \"%"
+            "s\").", (IArg)name, (IArg)type);
+    return (NULL);
+}
+
+/*
+ *  ======== Engine_getFxns ========
+ */
+IALG_Fxns *Engine_getFxns(Engine_Handle engine, String name, String type,
+        Bool *isLocal, Ptr *idmaFxns, Ptr *iresFxns, Int *groupId,
+        Engine_CachedMemType *memType)
+{
+    Engine_AlgDesc *alg;
+
+    if (engine == NULL) {
+        engine = Engine_getLocalEngine();
+    }
+
+    alg = getAlgDesc(NULL, engine, name);
+
+    if (alg && isa(alg, type)) {
+        *isLocal = alg->isLocal;
+        *idmaFxns = alg->idmaFxns;
+        *iresFxns = alg->iresFxns;
+        *groupId = alg->groupId;
+        *memType = alg->memType;
+        return (alg->fxns);
+    }
+
+    Log_print1(Diags_USER6,
+            "[+6] Engine_getFxns> Unable to locate alg \"%s\".", (IArg)name);
+
+    return (NULL);
+}
+
+/*
+ *  ======== Engine_getLocalEngine ========
+ */
+Engine_Handle Engine_getLocalEngine(Void)
+{
+    if (localEngine == NULL) {
+        localEngine = Engine_open(Engine_config.localEngine, NULL, NULL);
+    }
+
+    return (localEngine);
+}
+
+/*
+ *  ======== Engine_getMemId ========
+ */
+Int Engine_getMemId(Engine_Handle engine)
+{
+    if (engine == NULL) {
+        engine = Engine_getLocalEngine();
+    }
+
+    return (engine->rmsPoolId);
+}
+
+/*
+ *  ======== Engine_getEngine ========
+ */
+Engine_Handle Engine_getEngine(Engine_Node node)
+{
+    return (node->engine);
+}
+
+/*
+ *  ======== Engine_getCpuLoad ========
+ */
+Int Engine_getCpuLoad(Engine_Handle engine)
+{
+    RMS_RmsMsg *msg;
+
+    Log_print1(Diags_ENTRY, "[+E] Engine_getCpuLoad(0x%lx)", (IArg)engine);
+
+    /* This function is only valid for the Server CPU load */
+    if (engine->hasServer != TRUE) {
+        Log_print0(Diags_USER6,
+                "[+6] Engine_getCpuLoad> Only valid if there is a server");
+        engine->lastError = Engine_ERUNTIME;
+        return (-1);
+    }
+
+    if ((msg = (RMS_RmsMsg *)engine->rmsMsg) == NULL) {
+        engine->lastError = Engine_ERUNTIME;
+        return (-1);
+    }
+
+    /* init a "get CPU status" message */
+    msg->cmdBuf.cmd = RMS_GETCPUSTAT;
+    msg->cmdBuf.status = RMS_EFAIL;
+
+    callServer(engine, (Comm_Msg *)&msg);
+
+    engine->rmsMsg = (Comm_Msg)msg;
+
+    /* check that remote cmd succeeded */
+    if (msg->cmdBuf.status != RMS_EOK) {
+        engine->lastError = Engine_ERUNTIME;
+        return (-1);
+    }
+
+    return (msg->cmdBuf.data.getCpuStatOut.cpuLoad);
+}
+
+/*
+ *  ======== Engine_getLastError ========
+ */
+Engine_Error Engine_getLastError(Engine_Handle engine)
+{
+    return (engine->lastError);
+}
+
+/*
+ *  ======== Engine_getProcId ========
+ */
+String Engine_getProcId(Engine_Handle engine)
+{
+    Log_print1(Diags_ENTRY, "[+E] Engine_getProcId(0x%lx)", (IArg)engine);
+
+    return (engine->procId);
+}
+
+/*
+ *  ======== Engine_getServer ========
+ */
+Server_Handle Engine_getServer(Engine_Handle engine)
+{
+    Log_print1(Diags_ENTRY, "[+E] Engine_getServer(0x%lx)", (IArg)engine);
+
+    if (engine->hasServer) {
+        return ((Server_Handle)engine);
+    }
+    else {
+        engine->lastError = Engine_ENOSERVER;
+        return (NULL);
+    }
+}
+
+/*
+ *  ======== Engine_getCodecClassConfig ========
+ */
+Ptr Engine_getCodecClassConfig(Engine_Handle engine, String name, String type)
+{
+    Engine_AlgDesc *alg;
+    Engine_AlgDesc *algTab;
+
+    if (engine == NULL) {
+        engine = Engine_getLocalEngine();
+    }
+
+    algTab = engine->desc->algTab;
+
+    if (algTab != NULL) {
+        for (alg = algTab; alg->name != NULL; alg++) {
+            if (strcmp(name, alg->name) == 0) {
+                if (isa(alg, type)) {
+                    return (alg->codecClassConfig);
+                }
+            }
+        }
+    }
+
+    return (NULL);
+}
+
+/*
+ *  ======== Engine_initFromServer ========
+ */
+Engine_Error Engine_initFromServer(Engine_Handle engine)
+{
+    RMS_RmsMsg      *msg;
+    Int              index;
+    Int              i;
+    Int              len;
+    Char            *algName;
+    Char            *typeTab;
+    Char            *stubsName;
+    Engine_AlgDesc  *desc = NULL;
+    Engine_AlgDesc  *alg = NULL;
+    Int              numAlgs = 0;
+    Int              numRemoteAlgs = 0;
+    Engine_Error     status = Engine_EOK;
+
+
+    Log_print1(Diags_ENTRY, "[+E] Engine_initFromServer(0x%lx)", (IArg)engine);
+
+    if (engine->hasServer != TRUE) {
+        Log_print1(Diags_USER1, "[+1] Engine_initFromServer> Returning %d",
+                (IArg)status);
+        return (Engine_ENOSERVER);
+    }
+
+    /* Get the number of algs on the server */
+    status = Engine_getNumServerAlgs((Server_Handle)engine, &numAlgs);
+
+    if (status != Engine_EOK) {
+        Log_print1(Diags_USER7, "[+7] Engine_initFromServer> Failed to "
+                  "get number of server algs, returning %d", (IArg)status);
+        return (status);
+    }
+
+    if (numAlgs <= 0) {
+        /* Shouldn't happen, but just in case... */
+        Log_print1(Diags_USER6, "[+6] Engine_initFromServer> Server has "
+                  "no remote algs, returning %d", (IArg)status);
+        return (status);
+    }
+
+    /* Count the number of remote algs that were statically configured. */
+    alg = engine->desc->algTab;
+    numRemoteAlgs = 0;
+    for (; (alg != NULL) && (alg->name != NULL); alg++) {
+        if (alg->isLocal == FALSE) {
+            numRemoteAlgs++;
+        }
+    }
+
+    Log_print1(Diags_USER2, "[+2] Engine_initFromServer> Number of remote "
+            "algs statically configured in engine: %d", (IArg)numRemoteAlgs);
+
+    if (numAlgs == numRemoteAlgs) {
+        /*
+         *  ALl remote algs were statically configured. No need to get
+         *  information from the server.
+         */
+        Log_print1(Diags_USER2, "[+2] Engine_initFromServer> Number of "
+                "statically configured remote algs = number of server "
+                "algs: %d", (IArg)numAlgs);
+
+        Log_print1(Diags_USER1, "[+1] Engine_initFromServer> Returning %d",
+                (IArg)status);
+        return (status);
+    }
+
+    /*
+     *  Server contains remote algs that were not statically configured
+     *  into the engine. Allocate a table to hold server's alg info, and
+     *  get the alg info from the server.
+     */
+
+    Log_print1(Diags_USER2, "[+2] Engine_initFromServer> Allocating "
+            "descriptor array for [%d] server algs", (IArg)numAlgs);
+    desc = (Engine_AlgDesc *)Memory_alloc(sizeof(Engine_AlgDesc) * numAlgs,
+            NULL);
+    if (desc == NULL) {
+        Log_print0(Diags_USER7, "[+7] Engine_initFromServer> Failed "
+                "to allocate memory for engine table");
+        status = Engine_ENOMEM;
+    }
+
+    Log_print1(Diags_USER2, "[+2] Engine_initFromServer> Initializing "
+            "descriptor array for [%d] server algs", (IArg)numAlgs);
+    if (status == Engine_EOK) {
+        for (i = 0; i < numAlgs; i++) {
+            /*
+             *  Initialize desc fields that will be alloc'd so we don't
+             *  try to free invalid memory if something goes wrong.
+             */
+            desc[i].name = NULL;
+            desc[i].typeTab = NULL;
+        }
+    }
+
+    if (status == Engine_EOK) {
+        if ((msg = (RMS_RmsMsg *)engine->rmsMsg) == NULL) {
+            Log_print0(Diags_USER6, "[+6] Engine_initFromServer> "
+                    "internal error: rms message null");
+            status = Engine_ERUNTIME;
+        }
+    }
+
+    index = 0;
+    while ((status == Engine_EOK) && (index < numAlgs)) {
+        /* Get the info for alg 'index' */
+        msg->cmdBuf.cmd = RMS_GETALG;
+        msg->cmdBuf.status = RMS_EFAIL;
+        msg->cmdBuf.data.getAlgIn.index = index;
+
+        Log_print1(Diags_USER2, "[+2] Engine_initFromServer> "
+                "Sending RMS_GETALG command for alg [%d]", (IArg)index);
+        callServer(engine, (Comm_Msg *)&msg);
+
+        engine->rmsMsg = (Comm_Msg)msg;
+
+        /* check that remote cmd succeeded */
+        if (msg->cmdBuf.status == RMS_ENOTFOUND) {
+            /* Index is out of range (shouldn't happen), we're done. */
+            Log_print2(Diags_USER6, "[+6] Engine_initFromServer> WARNING "
+                    "Cannot get info for alg [%d], numAlgs = %d",
+                    (IArg)index, (IArg)numAlgs);
+            break;
+        }
+        else if (msg->cmdBuf.status != RMS_EOK) {
+            status = engine->lastError = Engine_ERUNTIME;
+            Log_print2(Diags_USER7, "[+7] Engine_initFromServer> "
+                    "failed to get information for alg [%d] from server. "
+                    "status = 0x%x", (IArg)index, (IArg)(msg->cmdBuf.status));
+        }
+        else {
+            /* Copy the codec name */
+            algName = (Char *)msg->cmdBuf.data.getAlgOut.name;
+            len = strlen(algName);
+            desc[index].name = Memory_alloc(len + 1, NULL);
+            if (desc[index].name == NULL) {
+                Log_print1(Diags_USER7, "[+7] Engine_initFromServer> "
+                        "Memory allocation for desc[%d].name failed!",
+                        index);
+                status = Engine_ENOMEM;
+                break;
+            }
+            strcpy(desc[index].name, algName);
+            desc[index].name[len] = '\0';
+
+            /*
+             *  Use a simplified typeTab, where strings are separated by ';'
+             *  instead of having an array of strings.
+             */
+            desc[index].typeTab = NULL;
+
+            typeTab = (Char *)msg->cmdBuf.data.getAlgOut.typeTab;
+            len = strlen(typeTab);
+            desc[index].types = Memory_alloc(len + 1, NULL);
+
+            if (desc[index].types == NULL) {
+                Log_print0(Diags_USER7, "[+7] Engine_initFromServer> "
+                        "Memory allocation for types failed!");
+                status = Engine_ENOMEM;
+                break;
+            }
+            strcpy(desc[index].types, typeTab);
+            desc[index].types[len] = '\0';
+
+            /*
+             *  Look up the stub functions in table. If they're not found,
+             *  just leave them as NULL. In that case the alg cannot be
+             *  used.
+             */
+            stubsName = (Char *)msg->cmdBuf.data.getAlgOut.stubFxns;
+            desc[index].fxns = NULL;
+            i = 0;
+
+            desc[index].fxns = getStubFxns(stubsName);
+            if (desc[index].fxns == NULL) {
+                Log_print1(Diags_USER6, "[+6] Engine_initFromServer> "
+                        "Warning: No stub functions were found for %s. "
+                        "The algorithm that requires these stub functions "
+                        "cannot be run remotely.", (IArg)stubsName);
+            }
+
+            desc[index].uuid = msg->cmdBuf.data.getAlgOut.uuid;
+
+            /* Don't care about groupId since alg is remote */
+            desc[index].groupId = -1;
+
+            desc[index].rpcProtocolVersion =
+                msg->cmdBuf.data.getAlgOut.rpcProtocolVersion;
+
+            /* Fill in the rest */
+            desc[index].idmaFxns = NULL;
+            desc[index].isLocal = FALSE;
+            desc[index].iresFxns = NULL;
+            desc[index].memType = Engine_USECACHEDMEM_DEFAULT;
+            desc[index].codecClassConfig = NULL;
+
+            /*
+             *  Print a warning if another alg of the same name already exists
+             *  in the static engine table.
+             */
+            alg = engine->desc->algTab;
+            algName = desc[index].name;
+            for (; (alg != NULL) && (alg->name != NULL); alg++) {
+                if ((strcmp(algName, alg->name) == 0) && alg->isLocal) {
+                    Log_print1(Diags_USER6, "[+6] Engine_initFromServer> "
+                            "WARNING: Local algorithm named \"%s\" in "
+                            "static engine table matches a server alg name. "
+                            "Behavior as to which algorithm will be created "
+                            "when using this name is undefined.",
+                            (IArg)(alg->name));
+                }
+            }
+
+            index++;
+        }
+    }
+
+    /*
+     *  Assign these even if an error occurred so we can call freeServerTab()
+     *  to clean things up.
+     */
+    engine->numRemoteAlgs = (desc == NULL) ? 0 : numAlgs;
+    engine->remoteAlgTab = desc;
+
+    if (status != Engine_EOK) {
+        /* Free anything allocated so far */
+        freeServerTab(engine);
+    }
+    else {
+        Log_print0(Diags_USER4, "[+4] Engine_initFromServer(): Found the "
+                "following server algs:");
+        for (i = 0; i < numAlgs; i++) {
+            Log_print1(Diags_USER4, "  %s: ", (IArg)desc[i].name);
+            Log_print1(Diags_USER4, "      rpcProtocolVersion: %d",
+                    (IArg)desc[i].rpcProtocolVersion);
+            Log_print2(Diags_USER4, "      uuid: %d [0x%x]",
+                    (IArg)desc[i].uuid.data, (IArg)desc[i].uuid.data);
+            Log_print1(Diags_USER4, "      type: %s",
+                    (IArg)desc[i].types);
+        }
+    }
+
+    Log_print1(Diags_USER1, "[+1] Engine_initFromServer engine->server = "
+            "0x%x\n", (IArg)(engine->server));
+
+    Log_print1(Diags_EXIT, "[+X] Engine_initFromServer> Returning %d",
+            (IArg)status);
+
+    return (status);
+}
+
+/*
+ *  ======== Engine_redefineHeap ========
+ */
+Engine_Error Engine_redefineHeap(Server_Handle server, String name,
+        Uint32 base, Uint32 size)
+{
+    Engine_Handle    engine = (Engine_Handle)server;
+    String           heapName;
+    RMS_RmsMsg      *msg;
+    Engine_Error     status = Engine_EOK;
+
+    Log_print4(Diags_ENTRY, "[+E] Engine_redefineHeap(0x%x %s 0x%x 0x%x)",
+            (IArg)engine, (IArg)name, (IArg)base, (IArg)size);
+
+    if (engine->hasServer != TRUE) {
+        return (Engine_ENOSERVER);
+    }
+
+    if ((msg = (RMS_RmsMsg *)engine->rmsMsg) == NULL) {
+        Log_print0(Diags_USER6,
+                "[+6] Engine_redefineHeap> internal error: rms message null");
+        return (Engine_ERUNTIME);
+    }
+
+    /* Set up command */
+    msg->cmdBuf.cmd = RMS_REDEFINEHEAP;
+    msg->cmdBuf.status = RMS_EFAIL;
+
+    heapName = (Char *)(msg->cmdBuf.data.redefineHeapIn.name);
+    strncpy(heapName, name, RMS_MAXSEGNAMELENGTH);
+    heapName[RMS_MAXSEGNAMELENGTH] = '\0';
+
+    msg->cmdBuf.data.redefineHeapIn.base = base;
+    msg->cmdBuf.data.redefineHeapIn.size = size;
+
+    callServer(engine, (Comm_Msg *)&msg);
+
+    engine->rmsMsg = (Comm_Msg)msg;
+
+    /* check that remote cmd succeeded */
+    if (msg->cmdBuf.status != RMS_EOK) {
+        if (msg->cmdBuf.status == RMS_EFREE) {
+            /* The heap is still in use on the DSP */
+            status = engine->lastError = Engine_EINUSE;
+        }
+        else if (msg->cmdBuf.status == RMS_EINVAL) {
+            status = engine->lastError = Engine_EINVAL;
+        }
+        else if (msg->cmdBuf.status == RMS_ENOTFOUND) {
+            status = engine->lastError = Engine_ENOTFOUND;
+        }
+        else {
+            status = engine->lastError = Engine_ERUNTIME;
+        }
+    }
+
+    return (status);
+}
+
+/*
+ *  ======== Engine_releaseTraceToken ========
+ */
+Bool Engine_releaseTraceToken(Server_Handle server)
+{
+    Engine_Handle engine = (Engine_Handle)server;
+    RMS_RmsMsg *msg;
+
+    if ((msg = (RMS_RmsMsg *)engine->rmsMsg) == NULL) {
+        engine->lastError = Engine_ERUNTIME;
+        return (FALSE);
+    }
+
+    /* init a "release trace token" message */
+    msg->cmdBuf.cmd = RMS_RELTRACETOKEN;
+    msg->cmdBuf.status = RMS_EFAIL;
+
+    callServer(engine, (Comm_Msg *)&msg);
+
+    engine->rmsMsg = (Comm_Msg)msg;
+
+    /* check that remote cmd succeeded */
+    if (msg->cmdBuf.status != RMS_EOK) {
+        return (FALSE);
+    }
+    else {
+        return (TRUE);
+    }
+}
+
+/*
+ *  ======== Engine_requestTraceToken ========
+ */
+Engine_Error Engine_requestTraceToken(Server_Handle server)
+{
+    Engine_Handle engine = (Engine_Handle)server;
+    Engine_Error status = Engine_ERUNTIME;
+    RMS_RmsMsg *msg;
+
+    if ((msg = (RMS_RmsMsg *)engine->rmsMsg) != NULL) {
+
+        /* init a "request trace token" message */
+        msg->cmdBuf.cmd = RMS_REQTRACETOKEN;
+        msg->cmdBuf.status = RMS_EFAIL;
+
+        callServer(engine, (Comm_Msg *)&msg);
+
+        engine->rmsMsg = (Comm_Msg)msg;
+
+        /* check if remote cmd succeeded */
+        if (msg->cmdBuf.status == RMS_EOK) {
+            status = Engine_EOK;
+        }
+        else if (msg->cmdBuf.status == RMS_ERESOURCE) {
+            status = Engine_EINUSE;
+        }
+    }
+
+    return(status);
+}
+
+/*
+ *  ======== Engine_restoreHeap ========
+ */
+Engine_Error Engine_restoreHeap(Server_Handle server, String name)
+{
+    Engine_Handle    engine = (Engine_Handle)server;
+    RMS_RmsMsg      *msg;
+    String           heapName;
+    Engine_Error     status = Engine_EOK;
+
+    Log_print1(Diags_ENTRY, "[+E] Engine_restoreHeap(0x%x)", (IArg)engine);
+
+    if (engine->hasServer != TRUE) {
+        return (Engine_ENOSERVER);
+    }
+
+    if ((msg = (RMS_RmsMsg *)engine->rmsMsg) == NULL) {
+        Log_print0(Diags_USER6,
+                "[+6] Engine_restoreHeap> internal error: rms message null");
+        return (Engine_ERUNTIME);
+    }
+
+    /* Set up command */
+    msg->cmdBuf.cmd = RMS_RESTOREHEAP;
+    msg->cmdBuf.status = RMS_EFAIL;
+
+    heapName = (Char *)(msg->cmdBuf.data.restoreHeapIn.name);
+    strncpy(heapName, name, RMS_MAXSEGNAMELENGTH);
+    heapName[RMS_MAXSEGNAMELENGTH] = '\0';
+
+    callServer(engine, (Comm_Msg *)&msg);
+
+    engine->rmsMsg = (Comm_Msg)msg;
+
+    /* check that remote cmd succeeded */
+    if (msg->cmdBuf.status != RMS_EOK) {
+        if (msg->cmdBuf.status == RMS_EFREE) {
+            /* The heap is still in use on the DSP */
+            status = engine->lastError = Engine_EINUSE;
+        }
+        else if (msg->cmdBuf.status == RMS_EINVAL) {
+            status = engine->lastError = Engine_EINVAL;
+        }
+        else if (msg->cmdBuf.status == RMS_ENOTFOUND) {
+            status = engine->lastError = Engine_ENOTFOUND;
+        }
+        else {
+            status = engine->lastError = Engine_ERUNTIME;
+        }
+    }
+
+    return (status);
+}
+
+/*
+ *  ======== Engine_fwriteTrace ========
+ */
+Int Engine_fwriteTrace(Engine_Handle engine, String prefix, FILE *out)
+{
+    RMS_RmsMsg *msg;
+    Int count = 0;
+    Int readCount = 0;
+    Bool newLine = TRUE;
+
+    /* this should really be the ENTER class but it obscures the output */
+    Log_print3(Diags_USER3, "[+3] Engine_fwriteTrace(0x%lx, '%s', 0x%lx)",
+            (IArg)engine, (IArg)prefix, (IArg)out);
+
+    if (engine->hasServer != TRUE) {
+        Log_print0(Diags_USER3,
+                "[+3] Engine_fwriteTrace> Engine has no server");
+        return (0);
+    }
+
+    if (!Server_holdingTraceToken) {
+        Log_print0(Diags_USER3, "[+3] Engine_fwriteTrace> Engine in use");
+        engine->lastError = Engine_EINUSE;
+        return (-1);
+    }
+
+    do {
+        UInt32 timeKey;
+
+        if ((msg = (RMS_RmsMsg *)engine->rmsMsg) == NULL) {
+            engine->lastError = Engine_ERUNTIME;
+            return (-1);
+        }
+
+
+        timeKey = Timestamp_get32();
+
+        /* init a "get trace" message */
+        msg->cmdBuf.cmd = RMS_GETTRACE;
+        msg->cmdBuf.status = RMS_EFAIL;
+        msg->cmdBuf.data.getTraceIn.curTime = timeKey;
+        msg->cmdBuf.data.getTraceOut.size = 0;
+        msg->cmdBuf.data.getTraceOut.lost = 0;
+
+        Log_print1(Diags_USER3,
+                "[+3] Engine_fwriteTrace(): requesting DSP trace @0x%x ...",
+                (IArg)timeKey);
+
+        /* send it to the DSP and wait for results ... */
+        callServer(engine, (Comm_Msg *)&msg);
+
+        engine->rmsMsg = (Comm_Msg)msg;
+
+        /* check that remote cmd succeeded */
+        if (msg->cmdBuf.status != RMS_EOK) {
+            engine->lastError = Engine_ERUNTIME;
+            return (-1);
+        }
+
+        Log_print5(Diags_USER3, "[+3] Engine_fwriteTrace> "
+                "got %d chars @0x%x (%d still avail, max: %d, lost: %d)",
+                (IArg)(msg->cmdBuf.data.getTraceOut.size), (IArg)timeKey,
+                (IArg)(msg->cmdBuf.data.getTraceOut.avail),
+                (IArg)(msg->cmdBuf.data.getTraceOut.max),
+                (IArg)(msg->cmdBuf.data.getTraceOut.lost));
+
+        readCount += msg->cmdBuf.data.getTraceOut.size;
+
+        if (msg->cmdBuf.data.getTraceOut.lost > 0) {
+            fprintf(out, " [ARM] WARNING: lost %d characters of DSP server trace "
+                    "due to buffer wrapping (got %d chars, %d left, max=%d; "
+                    "collect trace more often, or add "
+                    "Server.traceBufferSize = <largerSizeInBytes> "
+                    "to DSP server's .cfg file). %s",
+                    msg->cmdBuf.data.getTraceOut.lost,
+                    msg->cmdBuf.data.getTraceOut.size,
+                    msg->cmdBuf.data.getTraceOut.avail,
+                    msg->cmdBuf.data.getTraceOut.max, prefix );
+            newLine = FALSE;
+        }
+
+        /* write to file stream */
+        count += copyToFile((Char *)msg->cmdBuf.data.getTraceOut.buf,
+            msg->cmdBuf.data.getTraceOut.size, prefix, &newLine, out);
+
+    } while ((msg->cmdBuf.data.getTraceOut.avail > 0)
+        && (readCount < msg->cmdBuf.data.getTraceOut.max));
+
+    /* return number of characters actually copied */
+    Log_print1(Diags_EXIT, "[+X] Engine_fwriteTrace> returning count [%d]",
+            (IArg)count);
+    return (count);
+}
+
+/*
+ *  ======== Engine_getName ========
+ */
+String Engine_getName(Engine_Handle engine)
+{
+    return (engine->desc->name);
+}
+
+/*
+ *  ======== Engine_getRemoteVisa ========
+ */
+UInt32 Engine_getRemoteVisa(Engine_Node node)
+{
+    Assert_isTrue(node != NULL, (Assert_Id)NULL);
+
+    return (node->remoteVisa);
+}
+
+/*
+ *  ======== Engine_getNodeQueues ========
+ */
+Void Engine_getNodeQueues(Engine_Node node,
+    Comm_Id *stdIn, Comm_Handle *stdOut)
+{
+    if (node != NULL) {
+        *stdIn  = node->stdIn;
+        *stdOut = node->stdOut;
+    }
+    else {
+        *stdIn  = Comm_INVALIDMSGQ;
+        *stdOut = Comm_INVALIDHANDLE;
+    }
+}
+
+/*
+ *  ======== Engine_getUsedMem ========
+ */
+UInt32 Engine_getUsedMem(Engine_Handle engine)
+{
+    RMS_RmsMsg *msg;
+
+    Log_print1(Diags_ENTRY, "[+E] Engine_getUsedMem(0x%lx)", (IArg)engine);
+
+    if (engine->hasServer != TRUE) {
+        engine->lastError = Engine_ENOTAVAIL;
+        return (0);
+    }
+
+    if ((msg = (RMS_RmsMsg *)engine->rmsMsg) == NULL) {
+        engine->lastError = Engine_ERUNTIME;
+        return (0);
+    }
+
+    /* init a "node create" message */
+    msg->cmdBuf.cmd = RMS_GETMEMSTAT;
+    msg->cmdBuf.status = RMS_EFAIL;
+
+    callServer(engine, (Comm_Msg *)&msg);
+
+    engine->rmsMsg = (Comm_Msg)msg;
+
+    /* check that remote cmd succeeded */
+    if (msg->cmdBuf.status != RMS_EOK) {
+        engine->lastError = Engine_ERUNTIME;
+        return (0);
+    }
+
+    return (msg->cmdBuf.data.getMemStatOut.used);
+}
+
+/*
+ *  ======== Engine_hasServer ========
+ */
+Bool Engine_hasServer(Engine_Handle engine)
+{
+    if (engine) {
+        return (engine->hasServer);
+    }
+    else {
+        return (FALSE);
+    }
+}
+
+/*
+ *  ======== Engine_init ========
+ */
+Void Engine_init(Void)
+{
+    Engine_Desc      *desc = NULL;
+    Engine_AlgDesc   *alg = NULL;
+    Engine_AlgDesc   *algTab = NULL;
+    Int               numAlgs;
+    GateThread_Params gateParams;
+    Registry_Result   result;
+    Int32             numProcs;
+    int               i;
+    Engine_Error      status = Engine_EOK;
+
+    /*
+     *  No need to reference count for Registry_addModule(), since there
+     *  is no way to remove the module.
+     */
+    if (regInit == 0) {
+        /* Register this module for logging */
+        result = Registry_addModule(&ti_sdo_ce_Engine_desc, Engine_MODNAME);
+        Assert_isTrue(result == Registry_SUCCESS, (Assert_Id)NULL);
+
+        if (result == Registry_SUCCESS) {
+            /* Set the diags mask to the CE default */
+            CESettings_init();
+            CESettings_setDiags(Engine_MODNAME);
+        }
+        regInit = 1;
+    }
+
+    if (curInit != TRUE) {
+        curInit = TRUE;
+
+        if (Global_getenv("CE_DEBUG") != NULL) {
+            Log_print1(Diags_USER6, "[+6] Engine_init> CE debugging on "
+                    "(CE_DEBUG=%s; allowed CE_DEBUG levels: "
+                    "1=min, 2=good, 3=max)",
+                    (IArg)(Global_getenv("CE_DEBUG")));
+        }
+
+        Queue_new(&engineList);
+        Queue_new(&stubFxnsList);
+        Queue_new(&engineDescList);
+        Global_atexit((Fxn)cleanup);
+
+        GateThread_Params_init(&gateParams);
+        serverLock = GateThread_create(&gateParams, NULL);
+        assert(serverLock != NULL);
+
+        GateThread_Params_init(&gateParams);
+        traceLock = GateThread_create(&gateParams, NULL);
+        assert(traceLock != NULL);
+
+        GateThread_Params_init(&gateParams);
+        engineLock = GateThread_create(&gateParams, NULL);
+        assert(engineLock != NULL);
+
+        /*
+         *  For each engine, go through the alg table, and add the group ID
+         *  of each local alg. This enables run-time config apps to not
+         *  have to set up an array of group IDs that are used.
+         *
+         *  Also make sure the number of numAlgs in the engine desc matches the
+         *  number of algs in the engine desc algTab. Correct numAlgs, if
+         *  necessary (this mismatch is possible for run-time configuration,
+         *  where the engine table is set up with incorrect numAlgs).
+         */
+        for (desc = Engine_config.engineTab; desc->name != NULL; desc++) {
+            algTab = desc->algTab;
+
+            if (algTab != NULL) {
+                numAlgs = 0;
+                for (alg = algTab; alg->name != NULL; alg++) {
+                    numAlgs++;
+                    if (alg->isLocal) {
+                        Algorithm_addGroup(alg->groupId);
+                    }
+                }
+                if (desc->numAlgs != numAlgs) {
+                    Log_print3(Diags_USER5, "Engine_init> Descriptor for "
+                            "engine %s configured with %d algs. Setting to "
+                            "actual number of algs: %d.", (IArg)(desc->name),
+                            (IArg)(desc->numAlgs), (IArg)(numAlgs));
+                    desc->numAlgs = numAlgs;
+                }
+            }
+
+            /*
+             *  Add to the Engine descriptor list. TODO: We could statically
+             *  create a table at config time and just initialize the pointers
+             *  in Engine_init().
+             */
+            status = addEngineToList(desc, TRUE);
+
+            if (status != Engine_EOK) {
+                Log_print2(Diags_USER7,
+                        "Engine_init> Failed to add engine %s to list: %d",
+                        (IArg)desc->name, (IArg)status);
+            }
+        }
+
+        /* Allocate and initialize the server table - one elem per core */
+        numProcs = Processor_getNumProcs();
+        serverTab = Memory_alloc(sizeof(*serverTab) * numProcs, NULL);
+
+        for (i = 0; i < numProcs; i++) {
+            serverTab[i].dspProc = NULL;
+            serverTab[i].imageName = NULL;
+            serverTab[i].refCount = 0;
+        }
+    }
+}
+
+/*
+ *  ======== Engine_initAlgDesc ========
+ */
+Void Engine_initAlgDesc(Engine_AlgDesc *pAlgDesc)
+{
+    pAlgDesc->name = NULL;
+    pAlgDesc->uuid.data = 0;
+    pAlgDesc->fxns = NULL;
+    pAlgDesc->idmaFxns = NULL;
+    pAlgDesc->typeTab = NULL;
+    pAlgDesc->isLocal = TRUE;
+    pAlgDesc->groupId = 0;
+    pAlgDesc->rpcProtocolVersion = 0;
+    pAlgDesc->iresFxns = NULL;
+    pAlgDesc->codecClassConfig = NULL;
+    pAlgDesc->memType = Engine_USECACHEDMEM_DEFAULT;
+    pAlgDesc->types = NULL;
+}
+
+/*
+ *  ======== Engine_initAttrs ========
+ */
+Void Engine_initAttrs(Engine_Attrs *pAttrs)
+{
+    pAttrs->procId = NULL;
+}
+
+/*
+ *  ======== Engine_initDesc ========
+ */
+Void Engine_initDesc(Engine_Desc *pDesc)
+{
+    pDesc->name = NULL;
+    pDesc->remoteName = NULL;
+    pDesc->memMap = NULL;
+    pDesc->useExtLoader = FALSE;
+    pDesc->heapId = 0;
+}
+
+/*
+ *  ======== Engine_open ========
+ */
+Engine_Handle Engine_open(String name, Engine_Attrs *attrs, Engine_Error *ec)
+{
+    Engine_Handle engine;
+    Engine_DescListElem *descElem = NULL;
+    IArg          key;
+    Engine_Error  dummy;
+
+    if (ec == NULL) {
+        ec = &dummy;
+    }
+
+    Log_print3(Diags_ENTRY, "[+E] Engine_open> Enter('%s', 0x%lx, 0x%x)",
+            (IArg)name, (IArg)attrs, (IArg)ec);
+
+    /* Look for engine in dynamically allocated list */
+    key = GateThread_enter(engineLock);
+    descElem = getDescListElem(name);
+    if (descElem == NULL) {
+        GateThread_leave(engineLock, key);
+        *ec = Engine_EEXIST;
+        return (NULL);
+    }
+    descElem->refCount++;
+
+    Log_print2(Diags_USER1, "[+1] Engine_open> desc->memMap [0x%x], "
+               "desc->useExtLoader [%d]", (IArg)descElem->desc.memMap,
+            (IArg)descElem->desc.useExtLoader);
+
+    GateThread_leave(engineLock, key);
+
+    /* create Engine object */
+    engine = (Engine_Obj *)Memory_alloc(sizeof (struct Engine_Obj), NULL);
+    if (engine == NULL) {
+        key = GateThread_enter(engineLock);
+        descElem->refCount--;
+        GateThread_leave(engineLock, key);
+        *ec = Engine_ENOMEM;
+        return (NULL);
+    }
+
+    if (attrs == NULL) {
+        attrs = &Engine_ATTRS;
+    }
+
+    /* initialize Engine_Obj fields */
+    Queue_new(&engine->link);
+    engine->server = NULL;
+    engine->toRMS = Comm_INVALIDMSGQ;
+    engine->fromRMS = Comm_INVALIDHANDLE;
+
+    /*
+     * TODO:H - though assigned here, this is unconditionally
+     * overridden [for Engines with Servers] in rmsInit.  Either we
+     * should remove this desc->heapId field (as it's no longer used
+     * - and only introduced in CE 3.x), or we should understand how
+     * a user would configure it, and assign it 'good defaults'.  Maybe
+     * the default says "base the poolId on procId" and
+     * do what we're doing - but if the user wants to override it, they
+     * can configure it at runtime (e.g. the Engine name - "myEngine:1"?).
+     */
+    engine->rmsPoolId = descElem->desc.heapId;
+    engine->rmsMsg = NULL;
+    engine->desc = &(descElem->desc);
+    engine->hasServer = FALSE;
+    engine->remoteAlgTab = NULL;
+    engine->numRemoteAlgs = 0;
+    engine->loadedLibs = NULL;
+    engine->numLoadedLibs = 0;
+    engine->descElem = descElem;
+    engine->procId = attrs->procId;
+
+    /* initialize RMS communications */
+    engine = rmsInit(engine, ec);
+
+    if ((engine != NULL) && Engine_alwaysCollectDspTrace) {
+        collectDspTrace( engine );
+    }
+
+    /* Initialize alg table with server algs */
+    if (engine && engine->hasServer && ti_sdo_ce_Engine_initFromServer) {
+        *ec = Engine_initFromServer(engine);
+        if (*ec != Engine_EOK) {
+            Log_print1(Diags_USER6, "Engine_open> WARNING: Unable to "
+                    "initialize remote enging alg table from server. "
+                    "Status = %d", (IArg)*ec);
+        }
+    }
+
+    if (engine == NULL) {
+        key = GateThread_enter(engineLock);
+        descElem->refCount--;
+        GateThread_leave(engineLock, key);
+    }
+
+    Log_print1(Diags_EXIT, "[+X] Engine_open> return(0x%x)", (IArg)engine);
+
+    return (engine);
+}
+
+/*
+ *  ======== Engine_setTrace ========
+ */
+Int Engine_setTrace(Engine_Handle engine, String mask)
+{
+    RMS_RmsMsg *msg;
+    int         retVal = Engine_EOK;
+
+    Log_print2(Diags_ENTRY, "[+E] Engine_setTrace> "
+            "Enter(engine=0x%x, mask='%s')", (IArg)engine, (IArg)mask);
+
+    if (engine->hasServer != TRUE) {
+        retVal = Engine_ENOSERVER;
+        goto setTrace_return;
+    }
+
+    if (!Server_holdingTraceToken) {
+        retVal = Engine_EINUSE;
+        goto setTrace_return;
+    }
+
+    if ((msg = (RMS_RmsMsg *)engine->rmsMsg) == NULL) {
+        retVal = Engine_ERUNTIME;
+        goto setTrace_return;
+    }
+
+    /* init a "set trace" message */
+    msg->cmdBuf.cmd = RMS_SETTRACEMASK;
+    msg->cmdBuf.status = RMS_EFAIL;
+    strncpy((Char *)msg->cmdBuf.data.setTraceMaskIn.traceMask, mask,
+        RMS_MAXTRACEMASKSIZE);
+    if (strlen(mask) > RMS_MAXTRACEMASKSIZE) {
+        Log_print1(Diags_USER6, "[+6] Engine_setTrace> "
+                "Warning: server trace mask too long, truncated to %d chars.",
+                (IArg)RMS_MAXTRACEMASKSIZE);
+    }
+    Log_print0(Diags_USER1, "[+1] Engine_setTrace> "
+            "Requesting DSP set trace ...");
+
+    /* send it to the DSP and wait for results ... */
+    callServer(engine, (Comm_Msg *)&msg);
+
+    engine->rmsMsg = (Comm_Msg)msg;
+
+    /* check that remote cmd succeeded */
+    if (msg->cmdBuf.status != RMS_EOK) {
+        retVal = Engine_ERUNTIME;
+        goto setTrace_return;
+    }
+
+setTrace_return:
+
+    Log_print1(Diags_EXIT, "[+X] Engine_setTrace> return(%d)", (IArg)retVal);
+    return (retVal);
+}
+
+/*
+ *  ======== addAlg ========
+ *  Add alg descriptor to Engine's table
+ */
+static Engine_Error addAlg(String engName, Engine_Handle engine,
+        Engine_AlgDesc *pAlgDesc, Loader_Handle lib)
+{
+    Engine_DescListElem    *descElem;
+    _Engine_AlgLib    **loadedLibs = NULL;
+    Int                *numLoadedLibs;
+    _Engine_AlgLib     *algLib = NULL;
+    Int                 size;
+    String              algName;
+    String              algTypes = NULL;
+    Engine_Error        status = Engine_EOK;
+
+    Log_print2(Diags_ENTRY, "[+E] Engine addAlg(0x%x, 0x%x) ", (IArg)engine,
+            (IArg)pAlgDesc);
+
+    Assert_isTrue(pAlgDesc != NULL, (Assert_Id)NULL);
+    Assert_isTrue(pAlgDesc->name != NULL, (Assert_Id)NULL);
+
+    /*
+     *  This must be called within a GateThread_enter() / GateThread_leave()
+     *  block.
+     */
+
+    /*  Get the list to add the alg to */
+    if (engName) {
+        /*
+         *  The engine has not been opened yet (this has been checked
+         *  in Engine_addAlg()), so use the Engine's descriptor list that
+         *  will be accessible to all who open the engine.
+         */
+        descElem = getDescListElem(engName);
+        Assert_isTrue(descElem != NULL, (Assert_Id)NULL);
+
+        loadedLibs = &(descElem->loadedLibs);
+        numLoadedLibs = &(descElem->numLoadedLibs);
+    }
+    else {
+        /*
+         *  The engine has been opened so we'll be adding the alg to this
+         *  engine's object.  The alg will only be accessible through this
+         *  Engine's handle.
+         */
+        loadedLibs = &(engine->loadedLibs);
+        numLoadedLibs = &(engine->numLoadedLibs);
+    }
+
+    /* Allocate structure to hold alg and library information */
+    if (status == Engine_EOK) {
+        algLib = Memory_alloc(sizeof(_Engine_AlgLib), NULL);
+
+        if (algLib == NULL) {
+            Log_print1(Diags_USER7,
+                    "[+7] Engine addAlg> Memory_alloc (%d) failed",
+                    (IArg)sizeof(_Engine_AlgLib));
+            status = Engine_ENOMEM;
+        }
+    }
+
+    if (status == Engine_EOK) {
+        algLib->algDesc = *pAlgDesc;
+
+        algLib->lib = lib; /* lib will be NULL for non-dynamic case */
+        algLib->typeTab[0] = algLib->typeTab[1] = NULL;
+        algLib->algDesc.name = NULL;
+        algLib->algDesc.types = NULL;
+    }
+
+    /* Copy the alg name to the new alg descriptor */
+    algName = pAlgDesc->name;
+
+    if (status == Engine_EOK) {
+        size = strlen(algName) + 1;
+        algLib->algDesc.name = Memory_alloc(size, NULL);
+        if (algLib->algDesc.name == NULL) {
+            Log_print1(Diags_USER7,
+                    "[+7] Engine_addAlg> Memory_alloc(%d) alg name failed",
+                    (IArg)size);
+            status = Engine_ENOMEM;
+        }
+        else {
+            strcpy(algLib->algDesc.name, algName);
+        }
+    }
+
+    /* Copy the alg types to the new alg descriptor */
+    if (status == Engine_EOK) {
+        algTypes = pAlgDesc->types;
+        size = strlen(algTypes) + 1;
+        algLib->algDesc.types = Memory_alloc(size, NULL);
+        if (algLib->algDesc.types == NULL) {
+            Log_print1(Diags_USER7,
+                    "[+7] Engine_addAlg> Memory_alloc(%d) alg types failed",
+                    (IArg)size);
+            status = Engine_ENOMEM;
+        }
+        else {
+            strcpy(algLib->algDesc.types, algTypes);
+
+            /* Need to fill in typeTab for Engine_getAlgInfo() support */
+            algLib->typeTab[0] = algLib->algDesc.types;
+            algLib->algDesc.typeTab = algLib->typeTab;
+        }
+    }
+
+    /*
+     *  Pass groupId to Algorithm_addGroup() to create group semaphore if it
+     *  doesn't exist yet.
+     */
+    if (pAlgDesc->isLocal && !Algorithm_addGroup(pAlgDesc->groupId)) {
+        Log_print1(Diags_USER7, "[+7] Engine addAlg> Algorithm_addGroup(%d) "
+                "failed", (IArg)(pAlgDesc->groupId));
+
+        /* Don't know why this failed, assume memory allocation. */
+        status = Engine_ENOMEM;
+    }
+
+    if (status == Engine_EOK) {
+        Log_print6(Diags_USER1,
+                "[+1] Engine addAlg> Adding desc:\n"
+                "    uuid [0x%x],\n"
+                "    fxns [0x%x],\n"
+                "    idmaFxns [0x%x],\n"
+                "    iresFxns [0x%x],\n"
+                "    stub/skel config params [0x%x],\n"
+                "    types [%s]",
+                (IArg)(algLib->algDesc.uuid.data),
+                (IArg)(algLib->algDesc.fxns),
+                (IArg)(algLib->algDesc.idmaFxns),
+                (IArg)(algLib->algDesc.iresFxns),
+                (IArg)(algLib->algDesc.codecClassConfig),
+                (IArg)(algLib->algDesc.types));
+
+        algLib->next = *loadedLibs;
+        *loadedLibs = algLib;
+        (*numLoadedLibs)++;
+    }
+    else {
+        /* Clean up */
+        if (algLib) {
+            if (algLib->algDesc.name) {
+                Memory_free(algLib->algDesc.name, strlen(algName) + 1, NULL);
+            }
+            if (algLib->algDesc.types) {
+                Memory_free(algLib->algDesc.types, strlen(algTypes) + 1, NULL);
+            }
+            Memory_free(algLib, sizeof(_Engine_AlgLib), NULL);
+        }
+    }
+
+    return (status);
+}
+
+
+/*
+ *  ======== addEngineToList ========
+ */
+static Engine_Error addEngineToList(Engine_Desc *desc, Bool isStatic)
+{
+    Engine_DescListElem *descElem;
+    Int                 len;
+    IArg                key;
+    Engine_Error        status = Engine_EOK;
+
+    Log_print2(Diags_ENTRY, "[+E] Engine addEngineToList(0x%x, %d) ",
+            (IArg)desc, (IArg)isStatic);
+
+    /* Create Engine descriptor object */
+    descElem = Memory_alloc(sizeof(Engine_DescListElem), NULL);
+    if (descElem == NULL) {
+        Log_print0(Diags_USER7, "[+7] Engine_add> Memory_alloc() failed.");
+        return (Engine_ENOMEM);
+    }
+
+    Queue_new(&descElem->link);
+    descElem->refCount = 0;
+
+    /*
+     *  Initialize descriptor. For statically configured engines, we just
+     *  copy the descriptor and we're done. For dynamically added engines,
+     *  we allocate buffers for the engine's name and remote name and copy
+     *  these.
+     */
+    descElem->desc = *desc;
+    descElem->isStatic = isStatic;
+    descElem->loadedLibs = NULL;
+
+    if (!isStatic && (status == Engine_EOK)) {
+        descElem->desc.name = NULL;
+        descElem->desc.algTab = NULL;
+        descElem->desc.remoteName = NULL;
+        descElem->desc.memMap = NULL;
+        descElem->desc.numAlgs = 0;
+        /*
+         *  These fields are taken from user's descriptor:
+         *      descElem->desc.heapId
+         *      descElem->desc.useExtLoader
+         */
+
+        /* Copy the engine name into the descriptor */
+        descElem->desc.name = Memory_alloc(strlen(desc->name) + 1, NULL);
+        if (descElem->desc.name == NULL) {
+            Log_print0(Diags_USER7, "[+7] Engine_add> Memory_alloc() failed.");
+            status = Engine_ENOMEM;
+        }
+        else {
+            strcpy(descElem->desc.name, desc->name);
+        }
+
+        /* If the engine has a server name, copy it into the descriptor */
+        if ((status == Engine_EOK) && (desc->remoteName != NULL)) {
+            len = strlen(desc->remoteName) + 1;
+            descElem->desc.remoteName = Memory_alloc(len, NULL);
+
+            if (descElem->desc.remoteName == NULL) {
+                Log_print0(Diags_USER7,
+                        "[+7] Engine addEngineToList> Memory_alloc() failed.");
+                status = Engine_ENOMEM;
+            }
+            else {
+                strcpy(descElem->desc.remoteName, desc->remoteName);
+            }
+        }
+
+        /* If the engine has a map file name, copy it into the descriptor */
+        if ((status == Engine_EOK) && (desc->memMap != NULL)) {
+            len = strlen(desc->memMap) + 1;
+            descElem->desc.memMap = Memory_alloc(len, NULL);
+
+            if (descElem->desc.memMap == NULL) {
+                Log_print0(Diags_USER7,
+                        "[+7] Engine addEngineToList> Memory_alloc() failed.");
+                status = Engine_ENOMEM;
+            }
+            else {
+                strcpy(descElem->desc.memMap, desc->memMap);
+            }
+        }
+    }
+
+    if (status != Engine_EOK) {
+        if (descElem) {
+            if (!descElem->isStatic) {
+                if (descElem->desc.name) {
+                    len = strlen(descElem->desc.name) + 1;
+                    Memory_free(descElem->desc.name, len, NULL);
+                }
+
+                if (descElem->desc.remoteName) {
+                    len = strlen(descElem->desc.remoteName) + 1;
+                    Memory_free(descElem->desc.remoteName, len, NULL);
+                }
+
+                if (descElem->desc.memMap) {
+                    len = strlen(descElem->desc.memMap) + 1;
+                    Memory_free(descElem->desc.memMap, len, NULL);
+                }
+            }
+
+            Memory_free(descElem, sizeof(Engine_DescListElem), NULL);
+        }
+    }
+    else {
+        Log_print2(Diags_USER1, "[+1] Engine addEngineToList> Adding desc: "
+                "name = %s, remoteName = %s",
+                (IArg)descElem->desc.name, (IArg)descElem->desc.remoteName);
+
+        /* Add engine descriptor to the end of list */
+        Queue_put(&engineDescList, (Ptr)descElem);
+
+        key = GateThread_enter(engineLock);
+        numEngines++;
+        GateThread_leave(engineLock, key);
+    }
+
+    return (status);
+}
+
+
+/*
+ *  ======== allocNode ========
+ */
+static Engine_Node allocNode(Engine_Handle engine, String impId)
+{
+    Engine_Node node;
+
+    Log_print2(Diags_ENTRY, "[+E] Engine> allocNode "
+            "Enter(engine=0x%x, impId='%s')", (IArg)engine, (IArg)impId);
+
+    /* allocate local node object */
+    node = (Engine_NodeObj *)Memory_alloc(sizeof (Engine_NodeObj), NULL);
+    if (node == NULL) {
+        engine->lastError = Engine_ENOMEM;
+        return (NULL);
+    }
+
+    node->engine = engine;
+    node->impId = impId;
+
+    /* create Comm for messages from the "remote" node */
+    Log_print0(Diags_ENTRY, "[+E] Engine> allocNode(). Calling Comm_create("
+            "NULL, NULL)");
+    node->stdOut = Comm_create(NULL, NULL);
+    if (node->stdOut == NULL) {
+        freeNode(node);
+        engine->lastError = Engine_ENOCOMM;
+        return (NULL);
+    }
+
+    return (node);
+}
+
+/*
+ *  ======== callServer ========
+ */
+static RMS_Status callServer(Engine_Handle engine, Comm_Msg *msg)
+{
+    /* set reply queue to our fromRMS queue */
+    Comm_setReplyToHandle(*msg, engine->fromRMS);
+
+    /* sanity check! */
+    if (engine->toRMS == Comm_INVALIDMSGQ) {
+        /* Generally doesn't happen, but if Engine_open() failed,
+         * it's failure handling internally calls Engine_close(), which
+         * tries to get the trace off the Server via this call.  Just return
+         * error.
+         */
+        return (RMS_ENOTFOUND);
+    }
+
+    /* send create message to RMS */
+    if (Comm_put(engine->toRMS, *msg) == Comm_EOK) {
+        Int status;
+        /* wait for reply on fromRMS queue */
+        status = Comm_get(engine->fromRMS, msg, Comm_FOREVER);
+        assert(status == Comm_EOK);
+    }
+
+    return (((RMS_RmsMsg *)(*msg))->cmdBuf.status);
+}
+
+/*
+ *  ======== checkServer ========
+ */
+static Bool checkServer(Engine_Handle engine)
+{
+    /* This string is defined in ti/sdo/ce/libvers.xdt */
+
+    Log_print1(Diags_ENTRY, "[+E] checkServer(0x%lx)", (IArg)engine);
+
+    /*
+     *  TODO: Also send message to RMS to get the RPC protocol version
+     *  to make sure it matches.
+     */
+    if (ti_sdo_ce__versionString != NULL) {
+        String skey = getServerKey(engine);
+
+        if (skey == NULL || strcmp(skey, ti_sdo_ce__versionString) != 0) {
+            /* if skey == NULL, lastError has already been set */
+            if (skey != NULL) {
+                engine->lastError = Engine_EBADSERVER;
+            }
+            Log_print3(Diags_USER6, "[+6] checkServer(0x%lx) failed: "
+                    "server = '%s', engine = '%s'",
+                    (IArg)engine, (IArg)(skey == NULL ? "" : skey),
+                    (IArg)ti_sdo_ce__versionString);
+            return (FALSE);
+        }
+    }
+
+    return (TRUE);
+}
+
+/*
+ *  ======== cleanup ========
+ */
+static Void cleanup(Void)
+{
+    Engine_Desc      *desc;
+    Engine_AlgDesc   *algTab;
+    Engine_AlgDesc   *alg;
+    Engine_DescListElem *descElem;
+    Int32             numProcs;
+
+    if (curInit != FALSE) {
+        curInit = FALSE;
+
+        #if 0
+        while (Queue_head(&engineList) != &engineList) {
+            Engine_Handle engine = Queue_get(&engineList);
+            Engine_close(engine);
+        }
+        #endif
+
+        while (Queue_head(&stubFxnsList) != &stubFxnsList) {
+            Engine_StubFxnsElem *stubs = Queue_get(&stubFxnsList);
+            Memory_free(stubs, sizeof(Engine_StubFxnsElem), NULL);
+        }
+
+        while (Queue_head(&engineDescList) != &engineDescList) {
+            descElem = (Engine_DescListElem *)Queue_get(&engineDescList);
+
+            Log_print2(Diags_USER4, "Engine cleanup()> Num engines = %d, "
+                    "removing engine %s", (IArg)numEngines,
+                    (IArg)descElem->desc.name);
+            numEngines--;
+            if (!descElem->isStatic) {
+                /* TODO: Remove any algs in descElem->loadedLibs */
+
+                /* Free allocated 'name' and 'remoteName' */
+                if (descElem->desc.name) {
+                    Memory_free(descElem->desc.name,
+                            strlen(descElem->desc.name) + 1, NULL);
+                }
+                if (descElem->desc.remoteName) {
+                    Memory_free(descElem->desc.remoteName,
+                            strlen(descElem->desc.remoteName) + 1, NULL);
+                }
+                if (descElem->desc.memMap) {
+                    Memory_free(descElem->desc.memMap,
+                            strlen(descElem->desc.memMap) + 1, NULL);
+                }
+            }
+            Memory_free(descElem, sizeof(Engine_DescListElem), NULL);
+        }
+
+        for (desc = Engine_config.engineTab; desc->name != NULL; desc++) {
+            algTab = desc->algTab;
+
+            if (algTab != NULL) {
+                for (alg = algTab; alg->name != NULL; alg++) {
+                    if (alg->isLocal) {
+                        Algorithm_removeGroup(alg->groupId);
+                    }
+                }
+            }
+        }
+
+        if (serverLock != NULL) {
+            GateThread_delete(&serverLock);
+            serverLock = NULL;
+        }
+        if (engineLock != NULL) {
+            GateThread_delete(&engineLock);
+            engineLock = NULL;
+        }
+        if (traceLock != NULL) {
+            GateThread_delete(&traceLock);
+            traceLock = NULL;
+        }
+
+        if (serverTab) {
+            numProcs = Processor_getNumProcs();
+            Memory_free(serverTab, sizeof(*serverTab) * numProcs, NULL);
+        }
+
+        /* reinitialize static vars */
+        serverTab = NULL;
+        localEngine = NULL;
+    }
+}
+
+/*
+ *  ======== copyToFile ========
+ *  copy buffer to file stream with optional prefix in front of each line
+ */
+static Int copyToFile(Char *cp, Int size, String prefix, Bool *newLine,
+    FILE *out)
+{
+    Int count, i;
+    Int prefixLen = 0;
+
+    if ((prefix != NULL) && (prefix[0] != '\0')) {
+        prefixLen = strlen(prefix);
+    }
+
+    count = 0;
+    for (i = 0; i < size; i++) {
+        if (prefixLen > 0 && *newLine) {
+            fputs(prefix, out);
+            count += prefixLen;
+            *newLine = FALSE;
+        }
+
+        fputc(cp[i], out);
+        count++;
+
+        if (cp[i] == '\n') {
+            *newLine = TRUE;
+        }
+    }
+
+    return (count);
+}
+
+/*
+ *  ======== freeNode ========
+ */
+static Void freeNode(Engine_Node node)
+{
+    if (node != NULL) {
+        if (node->stdOut != NULL) {
+            Comm_delete(node->stdOut);
+        }
+
+        Memory_free(node, sizeof(Engine_NodeObj), NULL);
+    }
+}
+
+/*
+ *  ======== freeServerTab ========
+ *  Free the engine's remoteAlgTab.
+ */
+static Void freeServerTab(Engine_Handle engine)
+{
+    Engine_AlgDesc *desc;
+    Int             i;
+    Int             len;
+    Int             nAlgs = engine->numRemoteAlgs;
+
+
+    Log_print1(Diags_ENTRY, "[+E] Engine freeServerTab() enter(0x%x)",
+            (IArg)engine);
+
+    Log_print1(Diags_USER2, "[+2] Engine freeServerTab() engine->"
+            "numRemoteAlgs = %d", (IArg)nAlgs);
+
+    if (engine->remoteAlgTab == NULL) {
+        return;
+    }
+
+    for (i = 0; i < nAlgs; i++) {
+        desc = &(engine->remoteAlgTab[i]);
+
+        if (desc->name) {
+            Memory_free(desc->name, strlen(desc->name) + 1, NULL);
+        }
+        if (desc->types) {
+            len = strlen(desc->types) + 1;
+            Memory_free(desc->types, len, NULL);
+        }
+    }
+    Memory_free(engine->remoteAlgTab, nAlgs * sizeof(Engine_AlgDesc), NULL);
+
+    engine->numRemoteAlgs = 0;
+    engine->remoteAlgTab = NULL;
+
+    Log_print0(Diags_EXIT, "[+X] Engine freeServerTab() exit");
+}
+
+/*
+ *  ======== getAlgDesc ========
+ *  Find the alg descriptor with 'algName' from the many possibilities.
+ *  If the engine has not been opened, use the engine name to find the alg,
+ *  otherwise use the engine handle.
+ */
+static Engine_AlgDesc *getAlgDesc(String engName, Engine_Handle engine,
+        String algName)
+{
+    Engine_AlgDesc      *alg = NULL;
+    Engine_DescListElem *descElem;
+    Engine_AlgDesc      *algTab;
+    _Engine_AlgLib      *lib;
+    Int                  i;
+
+    /*
+     *  First go through algs in the Engine_DescListElem object. These include
+     *  all statically configured algs, and algs added to the engine while
+     *  it is not in the opened state.
+     */
+    /* Get the Engine descriptor from the list of engines */
+    descElem = (engine) ? engine->descElem : getDescListElem(engName);
+
+    if (descElem == NULL) {
+        Log_print0(Diags_USER7, "Engine getAlgDesc> Failed to find engine "
+                "discriptor in list");
+        return (NULL);
+    }
+
+    /* Static alg table */
+    algTab = descElem->desc.algTab;
+
+    if (algTab != NULL) {
+        for (alg = algTab; alg->name != NULL; alg++) {
+            if (strcmp(algName, alg->name) == 0) {
+                return (alg);
+            }
+        }
+    }
+
+    /* Algs added with Engine_addAlg() before Engine_open() */
+    lib = descElem->loadedLibs;
+    while (lib != NULL) {
+        if (strcmp(algName, lib->algDesc.name) == 0) {
+            return (&(lib->algDesc));
+        }
+        lib = lib->next;
+    }
+
+    if (engine) {
+        /* Now go through algs obtained from server */
+        algTab = engine->remoteAlgTab;
+
+        for (i = 0, alg = algTab; i < engine->numRemoteAlgs; i++, alg++) {
+            if (strcmp(algName, alg->name) == 0) {
+                return (alg);
+            }
+        }
+
+        /* Now go through algs added after Engine_open() */
+        lib = engine->loadedLibs;
+
+        while (lib != NULL) {
+            if (strcmp(algName, lib->algDesc.name) == 0) {
+                return (&(lib->algDesc));
+            }
+            lib = lib->next;
+        }
+    }
+
+    return (NULL);
+}
+
+/*
+ *  ======== getAlgDescNum ========
+ *  Get the alg descriptor for an algorithm given its index.
+ */
+static Engine_AlgDesc *getAlgDescNum(String engName, Engine_Handle engine,
+        Int index)
+{
+    Engine_AlgDesc      *alg = NULL;
+    Int                  i, n;
+    Engine_DescListElem *descElem;
+    _Engine_AlgLib      *algLib;
+
+    Log_print3(Diags_ENTRY, "[+E] getAlgDescNum('%s', 0x%lx, %d)",
+            (IArg)engName, (IArg)engine, (IArg)index);
+
+    Assert_isTrue(index >= 0, (Assert_Id)NULL);
+    Assert_isTrue((engName != NULL) || (engine != NULL), (Assert_Id)NULL);
+    Assert_isTrue((engName == NULL) || (engine == NULL), (Assert_Id)NULL);
+
+    /* Assume lock acquired by caller */
+
+    /* Get the Engine descriptor from the list of engines */
+    descElem = (engName) ? getDescListElem(engName) : engine->descElem;
+
+    if (descElem == NULL) {
+        return (NULL);
+    }
+
+    /* Static alg table */
+    if (index < descElem->desc.numAlgs) {
+        alg = &(descElem->desc.algTab[index]);
+        return (alg);
+    }
+
+    /* Engine's pre-opened added algs */
+    n = index - descElem->desc.numAlgs;
+    if (n < descElem->numLoadedLibs) {
+        algLib = descElem->loadedLibs;
+
+        for (i = 0; (i < n) && (algLib != NULL); i++) {
+            algLib = algLib->next;
+        }
+
+        /* algLib should never be NULL but log just in case */
+        if (algLib == NULL) {
+            Log_print3(Diags_USER7,
+                    "Engine getAlgDescNum> WARNING: Inconsistency in engine "
+                    "[%s] loadedLibs[%d] and numLoadedLibs [%d]!",
+                    (IArg)descElem->desc.name, (IArg)i, (IArg)n);
+        }
+        alg = (algLib != NULL) ? &(algLib->algDesc) : NULL;
+        return (alg);
+    }
+
+    if (engine == NULL) {
+        /*
+         *  Didn't find alg in Engine's tables and lists of 'pre-opened'
+         *  algs.  Don't check 'post-opened' list since engine handle is
+         *  NULL.
+         */
+        return (NULL);
+    }
+
+    /* Engine opened, check remote alg table */
+
+    /* Subtract off the number of pre-opened added algs */
+    n -= descElem->numLoadedLibs;
+
+    /* Check algs from Engine_initFromServer() */
+    if (n < engine->numRemoteAlgs) {
+        /* Alg in remote alg table */
+        alg = &(engine->remoteAlgTab[n]);
+        return (alg);
+    }
+
+    /* Subtract off number of algs in table filled by Engine_initFromServer */
+    n -= engine->numRemoteAlgs;
+
+    /* Check list of 'post-opened' added algs */
+    if (n < engine->numLoadedLibs) {
+        algLib = engine->loadedLibs;
+
+        for (i = 0; (i < n) && (algLib != NULL); i++) {
+            algLib = algLib->next;
+        }
+
+        if (algLib == NULL) {
+            /* Shouldn't happen, but we'll check for this anyway */
+            Log_print1(Diags_USER7, "Engine_getAlgInfo> Inconsistency "
+                    "in number of loaded libs and numLoadedLibs for "
+                    "engine %s", (IArg)engine->desc->name);
+        }
+        alg = (algLib != NULL) ? &(algLib->algDesc) : NULL;
+    }
+
+    return (alg);
+}
+
+/*
+ *  ======== getDescListElem ========
+ */
+static Engine_DescListElem *getDescListElem(String engName)
+{
+    Engine_DescListElem *next;
+
+    if (engName == NULL) {
+        return (NULL);
+    }
+
+    /* Go through list of engines looking for a match with engName */
+    next = Queue_next(&engineDescList);
+    while ((Queue_Elem *)next != &engineDescList) {
+        if (strcmp(next->desc.name, engName) == 0) {
+            /* Match found */
+            return (next);
+        }
+        next = Queue_next(next);
+    }
+
+    return (NULL);
+}
+
+
+/*
+ *  ======== getServerKey ========
+ */
+static String getServerKey(Engine_Handle engine)
+{
+    RMS_RmsMsg *msg;
+
+    if ((msg = (RMS_RmsMsg *)engine->rmsMsg) == NULL) {
+        engine->lastError = Engine_ERUNTIME;
+        return (NULL);
+    }
+
+    /* init a "node create" message */
+    msg->cmdBuf.cmd = RMS_GETVERS;
+    msg->cmdBuf.status = RMS_EFAIL;
+
+    callServer(engine, (Comm_Msg *)&msg);
+
+    engine->rmsMsg = (Comm_Msg)msg;
+
+    /* check that remote cmd succeeded */
+    if (msg->cmdBuf.status != RMS_EOK) {
+        engine->lastError = Engine_ERUNTIME;
+        return (NULL);
+    }
+
+    /* Check the protocol version */
+    if ((msg->cmdBuf.data.getVersOut.rpcMajor != RMS_VERSION_MAJOR) ||
+            (msg->cmdBuf.data.getVersOut.rpcSource != RMS_VERSION_SOURCE) ||
+            (msg->cmdBuf.data.getVersOut.rpcMinor < RMS_VERSION_MINOR)) {
+
+        Log_print1(Diags_USER6, "[+6] getServerKey(0x%lx) protocol mismatch: ",
+                (IArg)engine);
+        Log_print3(Diags_USER6,
+                "[+6]    server: major = %d, source key = %d, minor key = %d",
+                (IArg)(msg->cmdBuf.data.getVersOut.rpcMajor),
+                (IArg)(msg->cmdBuf.data.getVersOut.rpcSource),
+                (IArg)(msg->cmdBuf.data.getVersOut.rpcMinor));
+        Log_print3(Diags_USER6,
+                "[+6]    engine: major = %d, source key = %d, minor key = %d",
+                (IArg)RMS_VERSION_MAJOR, (IArg)RMS_VERSION_SOURCE,
+                (IArg)RMS_VERSION_MINOR);
+
+        engine->lastError = Engine_ERUNTIME;
+        return (NULL);
+    }
+
+    return ((String)msg->cmdBuf.data.getVersOut.vers);
+}
+
+/*
+ *  ======== getRpcProtocolVersion ========
+ */
+static Int getRpcProtocolVersion(Engine_Handle engine, NODE_Uuid uuid)
+{
+    _Engine_AlgLib *lib;
+    Engine_AlgDesc *alg;
+    Int i;
+    Int ver = -1;
+
+    /*
+     *  Note: We're assuming Engine_addAlg() cannot be used to add
+     *  algs to a server before the engine has been opened (since the
+     *  server would not have been loaded). Therefore, we don't need
+     *  to look in the Engine_DescListElem.loadedLibs.
+     */
+    if (engine->desc->algTab) {
+        for (alg = engine->desc->algTab; alg->name != NULL; alg++) {
+            if (NODE_uuidMatch(&(alg->uuid), &uuid)) {
+                /* match */
+                ver = alg->rpcProtocolVersion;
+                Log_print1(Diags_USER2, "[+2] Engine getRpcProtocolVersion(): "
+                           "returning %d", (IArg)ver);
+                return (ver);
+            }
+        }
+    }
+
+    /*
+     *  TODO: Remove?
+     *  Check remote table, if not found in static table.
+     *  Note: This is pointless.  We get the rpcProtocolVersion from the
+     *  server, so of course it will match.
+     */
+    if (engine->remoteAlgTab) {
+        for (i = 0; i < engine->numRemoteAlgs; i++) {
+            if (NODE_uuidMatch(&(engine->remoteAlgTab[i].uuid), &uuid)) {
+                ver = engine->remoteAlgTab[i].rpcProtocolVersion;
+                Log_print1(Diags_USER2, "[+2] Engine getRpcProtocolVersion(): "
+                           "returning %d", (IArg)ver);
+                return (ver);
+            }
+        }
+    }
+
+    /*
+     *  TODO: Remove?
+     *  Check the dynamically loaded algs list.
+     *  Note: Also pointless.
+     */
+    for (lib = engine->loadedLibs; lib != NULL; lib = lib->next) {
+        alg = &(lib->algDesc);
+        if (NODE_uuidMatch(&(alg->uuid), &uuid)) {
+            /* match */
+            ver = alg->rpcProtocolVersion;
+            return (ver);
+        }
+    }
+
+    Log_print1(Diags_USER2, "[+2] Engine getRpcProtocolVersion(): "
+            "returning %d", (IArg)ver);
+    return (ver);
+}
+
+/*
+ *  ======== getStubFxns ========
+ */
+static IALG_Fxns *getStubFxns(String stubFxnsName)
+{
+    Engine_StubFxnsElem *stubs;
+
+    stubs = (Engine_StubFxnsElem *)Queue_head(&stubFxnsList);
+    while ((Queue_Elem *)stubs != &stubFxnsList) {
+        if ((strcmp(stubFxnsName, stubs->name)) == 0) {
+            /* Found match */
+            return (stubs->stubFxns);
+        }
+        stubs = Queue_next(stubs);
+    }
+
+    return (NULL);
+}
+
+/*
+ *  ======== isa ========
+ */
+static Bool isa(Engine_AlgDesc *alg, String type)
+{
+    String  tp;
+    Char   *endStr = NULL;
+    Char   *begStr = NULL;
+    Char    sep = ';';
+    Int     len;
+
+    // TODO: Temp, until typeTab[] is removed.
+    if (alg->types == NULL) {
+        alg->types = alg->typeTab[0];
+    }
+
+    if ((tp = alg->types) != NULL) {
+        if ((endStr = strchr(tp, sep)) == NULL) {
+            /* Just one type, not multiple types separated by ';' */
+            if (strcmp(tp, type) == 0) {
+                return (TRUE);
+            }
+        }
+        else {
+            /* multiple types, separated by ';' */
+            begStr = tp;
+            while ((begStr != NULL) && (*begStr != '\0')) {
+                len = (endStr != NULL) ? endStr - begStr : strlen(begStr);
+                if ((strncmp(begStr, type, len) == 0) &&
+                        (strlen(type) == len)) {
+                    return (TRUE);
+                }
+
+                begStr = (endStr == NULL) ? NULL : endStr + 1;
+                endStr = (endStr == NULL) ? NULL : strchr(begStr, sep);
+            }
+
+            if (endStr == NULL) {
+                return (FALSE);
+            }
+        }
+    }
+
+    return (FALSE);
+}
+
+/*
+ *  ======== name2Uuid ========
+ *  Get the UUID of the algorithm.
+ *  This id is used on the server-side to lookup the appropriate NODE_Desc;
+ *  i.e., the skeleton fxns, stack size, priority, etc.
+ */
+static Void name2Uuid(Engine_Handle engine, String algName, NODE_Uuid *uuid)
+{
+    Engine_AlgDesc *alg;
+
+    alg = getAlgDesc(NULL, engine, algName);
+    if (alg) {
+        *uuid = alg->uuid;
+    }
+}
+
+/*
+ *  ======== rmsInit ========
+ */
+static Engine_Handle rmsInit(Engine_Obj *engine, Engine_Error *ec)
+{
+    Int             status;
+    Engine_AlgDesc *alg;
+    String          algName = NULL;
+    Bool            startedServer = FALSE;
+    String          traceMask = NULL;
+    char            rmsCommName[32];  /* MessageQ_max length(?) */
+    UInt32          coreId;
+
+    Log_print2(Diags_ENTRY, "[+E] rmsInit> Enter(engine=0x%x, ec=0x%x)",
+            (IArg)engine, (IArg)ec);
+
+    /*
+     *  Go through the list of algorithms, checking for non-local to
+     *  determine whether or not to start the server.
+     */
+    Log_print1(Diags_USER1, "[+E] rmsInit> engine->desc = 0x%x",
+            (IArg)engine->desc);
+    Log_print1(Diags_USER1, "[+E] rmsInit> engine->desc->algTab = 0x%x",
+            (IArg)engine->desc->algTab);
+    alg = engine->desc->algTab;
+    for (; (alg != NULL) && (alg->name != NULL); alg++) {
+        if (alg->isLocal != TRUE) {
+            Log_print1(Diags_USER1, "[+E] rmsInit> found remote alg %s",
+                    (IArg)alg->name);
+            algName = alg->name;
+            break;
+        }
+    }
+
+    /*
+     *  Connect to remote proc if there are remote algs or the name of
+     *  a server program is non-NULL.
+     */
+    if ((algName != NULL) || (engine->desc->remoteName != NULL)) {
+        engine->hasServer = TRUE;
+
+        Log_print0(Diags_USER1, "[+E] rmsInit> engine has server!");
+
+        /* If engine->procId isn't set, initialize it to core 0 */
+        /*
+         * Note, core 0 can be confusing.  On a homogeneous, BIOS-only,
+         * multicore device, like 6472, core 0 is typically the app core
+         * (with cores 1-5 being the slaves).  On a heterogeneous,
+         * SysLink-based device, like OMAP3, core 0 is typically a slave.
+         * This fundamental difference makes it difficult to decide what to do
+         * in this 'default' case (an ideal default would be the 'first slave',
+         * but because of these environmental differences, we don't know if
+         * that's core 0 or core 1!).  So when not specified, the 'default'
+         * core is core 0.
+         */
+        if (engine->procId == NULL) {
+            engine->procId = Processor_getCoreName(0);
+        }
+
+        Log_print1(Diags_USER1, "[+E] rmsInit> engine->procId = %s",
+                (IArg)engine->procId);
+
+        /* [potentially] get the heap id for communicating with remote proc */
+        coreId = Processor_getCoreId(engine->procId);
+
+        /* Make sure engine->procId is valid */
+        if (coreId == Processor_INVALIDID) {
+            Log_print1(Diags_USER7, "[+7] rmsInit> Invalid procId: %s",
+                (IArg)engine->procId);
+            goto fail;
+        }
+
+        engine->rmsPoolId = Processor_getHeapId(coreId);
+
+        Log_print1(Diags_USER1, "[+E] rmsInit> engine->coreId = %d",
+                (IArg)coreId);
+
+        if (engine->procId == NULL) {
+            /* strange, but supported, the "remote" server is on this proc */
+            engine->server = NULL;
+        }
+        else {
+            /* connect to RMS on remote server */
+            engine->server = rserverOpen(engine->desc, &startedServer,
+                    engine->procId);
+            if (engine->server == NULL) {
+                *ec = Engine_EDSPLOAD;
+                goto fail;
+            }
+        }
+
+        /* create a message queue for RMS replies (pass NULL for name) */
+        engine->fromRMS = Comm_create(NULL, NULL);
+        if (engine->fromRMS == NULL) {
+            *ec = Engine_ENOCOMM;
+            goto fail;
+        }
+
+        /* allocate message to exchange with RMS */
+        status = Comm_alloc(engine->rmsPoolId,
+                (Comm_Msg *)&engine->rmsMsg, sizeof (RMS_RmsMsg));
+        if (status != Comm_EOK) {
+            *ec = Engine_ECOMALLOC;
+            goto fail;
+        }
+
+        /* locate core-specific RMS's message queue */
+        sprintf(rmsCommName, RMS_CMDQNAME ":%s", engine->procId);
+        status = Comm_locate(rmsCommName, &engine->toRMS);
+        if (status != Comm_EOK) {
+            *ec = Engine_ENOSERVER;
+            goto fail;
+        }
+
+        /* check server compatibility key */
+        if (checkServer(engine) != TRUE) {
+            *ec = engine->lastError;
+            goto fail;
+        }
+    }
+
+    /* put opened engine on engineList */
+    Queue_put(&engineList, &engine->link);
+    *ec = Engine_EOK;
+
+    /* if started up server optionally set the DSP trace mask */
+    if (startedServer == TRUE) {
+        if (Engine_alwaysCollectDspTrace) {
+            Log_print2(Diags_ENTRY,
+                    "[+E] rmsInit> RMS initialized(0x%lx); CE_DEBUG on, "
+                    "setting DSP trace mask to %s",
+                    (IArg)engine, (IArg)Engine_ceDebugDspTraceMask);
+            Engine_setTrace(engine, Engine_ceDebugDspTraceMask);
+        }
+        if ((traceMask = Global_getenv("CE_DSP0TRACE")) != NULL) {
+            Log_print2(Diags_ENTRY,
+                    "[+E] rmsInit(0x%lx), setting DSP trace mask to %s",
+                    (IArg)engine, (IArg)traceMask);
+            Engine_setTrace(engine, traceMask);
+        }
+    }
+
+    return (engine);
+
+fail:
+
+    Engine_close(engine);
+
+    return (NULL);
+}
+
+/*
+ *  ======== rserverClose ========
+ */
+static Void rserverClose(RServer server)
+{
+    IArg key;
+
+    key = GateThread_enter(serverLock);
+    Log_print2(Diags_ENTRY, "[+E] rserverClose(0x%lx), count = %d",
+            (IArg)server, (IArg)(server->refCount));
+
+    /* decrement reference count */
+    if (server->refCount-- == 1) {
+        /* if no more references exist, turn off the DSP */
+        Processor_delete(server->dspProc);
+    }
+
+    Log_print1(Diags_EXIT, "[+X] rserverClose(0x%lx) done.", (IArg)server);
+    GateThread_leave(serverLock, key);
+}
+
+/*
+ *  ======== rserverDetach ========
+ */
+static Void rserverDetach(Engine_Handle engine)
+{
+    IArg        key;
+    RMS_RmsMsg *msg;
+    RServer     server = engine->server;
+
+    Log_print2(Diags_ENTRY, "[+E] rserverDetach(0x%lx), count = %d",
+            (IArg)server, (IArg)(server->refCount));
+
+    key = GateThread_enter(serverLock);
+
+    /* Reference count will be decremented in rserverClose() */
+    if (server->refCount == 1) {
+        if ((msg = (RMS_RmsMsg *)engine->rmsMsg) == NULL) {
+            Log_print0(Diags_USER6, "[+6] rserverDetach() NULL rmsMsg");
+            engine->lastError = Engine_ERUNTIME;
+            GateThread_leave(serverLock, key);
+            return;
+        }
+
+        /* init a "node create" message */
+        msg->cmdBuf.cmd = RMS_DETACH;
+        msg->cmdBuf.status = RMS_EFAIL;
+
+        callServer(engine, (Comm_Msg *)&msg);
+
+        engine->rmsMsg = (Comm_Msg)msg;
+
+        /* check that remote cmd succeeded */
+        if (msg->cmdBuf.status != RMS_EOK) {
+            Log_print1(Diags_USER6, "[+6] rserverDetach() remote command "
+                       "failed: [%d]", (IArg)msg->cmdBuf.status);
+            engine->lastError = Engine_ERUNTIME;
+        }
+    }
+
+    GateThread_leave(serverLock, key);
+
+    Log_print1(Diags_EXIT, "[+X] rserverDetach(0x%lx) done.", (IArg)server);
+}
+
+/*
+ *  ======== rserverOpen ========
+ */
+static RServer rserverOpen(Engine_Desc * desc, Bool * startedServer,
+        String procId)
+{
+    IArg    key;
+    RServer server = &serverTab[Processor_getCoreId(procId)];
+
+    key = GateThread_enter(serverLock);
+    Log_print2(Diags_ENTRY, "[+E] rserverOpen('%s'), count = %d",
+            (IArg)(desc->remoteName), (IArg)(server->refCount));
+
+    Log_print2(Diags_ENTRY, "[+E] rserverOpen >, memMap = 0x%x, "
+            "useExtLoader = %d",
+            (IArg)(desc->memMap), (IArg)(desc->useExtLoader));
+
+    if (server->refCount == 0) {
+        /* if no references exist, initialize the Server */
+        Processor_Attrs attrs = Processor_ATTRS;
+
+        attrs.argv = NULL;
+        attrs.argc = 0;
+        attrs.cpuId = procId;
+        attrs.useExtLoader = desc->useExtLoader;
+
+        if ((server->dspProc = Processor_create(desc->remoteName,
+            desc->memMap, &attrs)) != NULL) {
+            server->imageName = desc->remoteName;
+            *startedServer = TRUE;
+        }
+        else {
+            /* failed to "create" the server, return NULL */
+            Log_print1(Diags_USER6,
+                    "[+6] rserverOpen: can't start '%s'; Processor_create "
+                    "failed", (IArg)(desc->remoteName));
+            server = NULL;
+        }
+    }
+    else {
+        if (strcmp(server->imageName, desc->remoteName) != 0) {
+            Log_print2(Diags_USER6,
+                    "[+6] rserverOpen: can't start '%s'; '%s' already running",
+                    (IArg)(desc->remoteName), (IArg)(server->imageName));
+            server = NULL;
+        }
+    }
+
+    if (server != NULL) {
+        server->refCount++;
+    }
+
+    Log_print2(Diags_EXIT, "[+X] rserverOpen('%s'): 0x%lx done.",
+            (IArg)(desc->remoteName), (IArg)server);
+    GateThread_leave(serverLock, key);
+
+    return (server);
+}
+
+/*
+ *  ======== Engine_getNumEngines ========
+ *  This function is only used for testing.
+ */
+Int Engine_getNumEngines()
+{
+    return (numEngines);
+}
+
+
+/*
+ *  ======== _Engine_getDesc ========
+ *  This function is only used for testing.
+ */
+Engine_Desc *_Engine_getDesc(Int n)
+{
+    Engine_DescListElem *descElem;
+    Engine_Desc         *desc = NULL;
+    Int                  i;
+
+    Log_print1(Diags_ENTRY, "[+E] _Engine_getDesc(%d)", (IArg)n);
+
+    i = 0;
+    descElem = (Engine_DescListElem *)Queue_next(&engineDescList);
+
+    while (((Queue_Elem *)descElem != &engineDescList) && (i < n)) {
+        descElem = Queue_next(descElem);
+        i++;
+    }
+
+    if ((Queue_Elem *)descElem != &engineDescList) {
+        desc = &(descElem->desc);
+    }
+    else {
+        Log_print2(Diags_USER6, "[+6] _Engine_getDesc> The index of the "
+                "Engine descriptor object requested exceeds the maximum "
+                "available: requested index = %d, num descriptors = %d",
+                (IArg)n, (IArg)i);
+    }
+
+    return (desc);
+}
diff --git a/packages/ti/sdo/ce/Engine.h b/packages/ti/sdo/ce/Engine.h
new file mode 100644 (file)
index 0000000..2bb3d63
--- /dev/null
@@ -0,0 +1,1574 @@
+/*
+ * Copyright (c) 2013, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * *  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * *  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * *  Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/*
+ *  ======== Engine.h ========
+ */
+
+/**
+ *  @file       ti/sdo/ce/Engine.h
+ *
+ *  @brief      The Codec Engine Runtime.
+ *
+ *  @remarks    Provides the user an interface to
+ *              open and manipulate an Engine which can instantiate
+ *              and communicate with XDAIS algorithms that run either
+ *              on the local CPU or on a "remote" Server.
+ */
+/**
+ *  @addtogroup   CODECENGINE     Codec Engine Runtime
+ */
+
+#ifndef Engine_
+#define Engine_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include <ti/sdo/ce/ServerDefs.h>
+#include <ti/sdo/ce/ipc/Comm.h>
+#include <ti/xdais/ialg.h>
+#include <ti/sdo/ce/node/node.h>
+
+#include <stddef.h> /* def of size_t */
+#include <stdio.h>  /* def of FILE * */
+
+/** @ingroup    CODECENGINE */
+/*@{*/
+
+/**
+ * @brief       Name to pass to Diags_setMask() to enable logging for Engine
+ *              functions.
+ *
+ * @par Example Usage:
+ *              The following code turns on all Log statements in the Engine
+ *              module.
+ * @code
+ *     Diags_setMask(Engine_MODNAME "+EX1234567");
+ * @endcode
+ *
+ * @remarks     Using Diags_setMask() to enable Engine Logging must be called
+ *              after CERuntime_init() (which creates and initializes the
+ *              Engine trace mask) to have any effect.
+ */
+#define Engine_MODNAME "ti.sdo.ce.Engine"
+
+/**
+ *  @brief      Opaque handle to an engine.
+ */
+typedef struct Engine_Obj *Engine_Handle;
+
+/**
+ *  @brief      Engine error code
+ */
+typedef Int Engine_Error;
+
+#define Engine_EOK          0   /**< Success. */
+#define Engine_EEXIST       1   /**< Name does not exist. */
+#define Engine_ENOMEM       2   /**< Unable to allocate memory. */
+#define Engine_EDSPLOAD     3   /**< Unable to load the DSP. */
+#define Engine_ENOCOMM      4   /**< Unable to create a comm connection to
+                                 *   the DSP.
+                                 */
+#define Engine_ENOSERVER    5   /**< Unable to locate the server on the DSP. */
+#define Engine_ECOMALLOC    6   /**< Unable to allocate communication buffer. */
+#define Engine_ERUNTIME     7   /**< Internal engine runtime failure. */
+#define Engine_ECODECCREATE 8   /**< Creation of the Codec failed. */
+#define Engine_ECODECSTART  9   /**< Start of the Codec failed.  For codecs
+                                 *   which are implemented as a thread, this
+                                 *   implies that the codec thread of execution
+                                 *   failed to start.
+                                 */
+#define Engine_EINVAL       10  /**< Bad paramater passed to method. */
+#define Engine_EBADSERVER   11  /**< Incompatible server specified. */
+#define Engine_ENOTAVAIL    12  /**< Service not available. */
+#define Engine_EWRONGSTATE  13  /**< Call can not be made at this time. */
+#define Engine_EINUSE       14  /**< Call can't be made at this time because
+                                 *   a required name/resource is in use.
+                                 */
+#define Engine_ENOTFOUND    15  /**< Entity was not found. */
+#define Engine_ETIMEOUT     16  /**< Timeout-based operation timed out. */
+
+/** @cond INTERNAL */
+
+/**
+ *  @brief      Opaque handle to a node.
+ */
+typedef struct Engine_NodeObj *Engine_Node;
+
+/**
+ *  @brief      Special value for timeout parameter of Engine_callWait()
+ */
+#define Engine_FOREVER Comm_FOREVER
+
+/** @endcond */
+
+/**
+ *  @brief      Attributes of an Engine
+ *
+ *  @sa         Engine_initAttrs().
+ *  @sa         Engine_open().
+ */
+typedef struct Engine_Attrs {
+    String procId;  /**< id of the processor that runs the server; only
+                     *   needed in the case that there's more than one
+                     *   processor that can provide the same server.
+                     */
+} Engine_Attrs;
+
+/**
+ *  @brief      Properties of an Engine algorithm
+ *
+ *  @sa         Engine_getAlgInfo()
+ */
+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;
+
+/**
+ *  @brief      Properties of an Engine algorithm.
+ *
+ *  @remarks    This structure is identical to Engine_AlgInfo except that the
+ *              @c typeTab array of strings is replaced by a single string
+ *              called @c types. The string, @c types, represents a ';'
+ *              separated list of inheritance hierarchies of the algorithm,
+ *              for example,
+ *              "ti.sdo.ce.video.IVIDDEC;ti.sdo.ce.test.xvideo.IVIDE".
+ *
+ *  @sa         Engine_getAlgInfo2()
+ */
+typedef struct Engine_AlgInfo2 {
+    Int         algInfoSize;    /**< Size of this structure. */
+    String      name;           /**< Name of algorithm. */
+    String      types;          /**< Inheritance hierarchy. */
+    Bool        isLocal;        /**< If TRUE, run locally. */
+} Engine_AlgInfo2;
+
+/**
+ *  @brief      Default engine attributes.
+ *
+ *  @deprecated Engine_ATTRS is no longer recommended. Please use
+ *              Engine_initAttrs() instead.
+ *
+ *  @sa Engine_initAttrs()
+ */
+extern Engine_Attrs Engine_ATTRS;    /**< Default attrs. */
+
+/** @cond INTERNAL */
+
+typedef Int Engine_Ctrl;
+
+#define Engine_CEXIT    0
+#define Engine_MAXSEGNAMELENGTH 32
+
+/** @endcond */
+
+/**
+ *  @brief      Engine Cacheable Memory types.
+ *
+ *  @enumWarning
+ */
+typedef enum Engine_CachedMemType {
+    Engine_USECACHEDMEM_DEFAULT = -1,  /**< Use default cache setting */
+    Engine_USECACHEDMEM_NONCACHED = 0, /**< Use non-cached memory */
+    Engine_USECACHEDMEM_CACHED = 1     /**< Use cached memory */
+} Engine_CachedMemType;
+
+
+/*
+ *  ======== Engine_AlgDesc ========
+ */
+/**
+ *  @brief      Descriptor for an alg. This object can be passed to
+ *              @c Engine_addAlg(), to dynamically add an alg to an engine.
+ *
+ *  @sa         Engine_initAlgDesc()
+ *  @sa         Engine_addAlg()
+ */
+typedef struct Engine_AlgDesc {
+    /**
+     *  @brief  The name of the algorithm. This is used by the application
+     *          when instantiating an instance of the algorithm through one
+     *          of the VISA APIs.
+     */
+    String      name;
+
+    NODE_Uuid   uuid;   /**< Id of alg if running on remote target. No need
+                         *   to set this field.
+                         */
+
+    /**
+     *  @brief  The address of the XDAIS alg function table.
+     *          All XDAIS algorithms must define an IALG_Fxns structure that
+     *          contains implementations of the IALG methods.  This field
+     *          is simply the address of this structure.
+     */
+    IALG_Fxns   *fxns;
+
+    /**
+     *  @brief  The address of the IDMA3_Fxns function table, if the algorithm
+     *          uses DMA. If the algorithm does not use DMA, this field should
+     *          set to NULL.
+     *  @idmaDeprecated
+     */
+    Ptr         idmaFxns;
+
+    String      *typeTab;       /**< inheritance hierarchy - Do not modify. */
+
+    /**
+     *  @brief  If true, the algorithm will be instantiated on the
+     *          "local" CPU.  Otherwise the server will create an
+     *           instance of the algorithm.
+     */
+    Bool        isLocal;
+
+    /**
+     *  @brief  This id specifies which resource sharing group that this
+     *          alg will be placed into.  This 'group' concept
+     *          is used by the framework to ensure algorithms in the
+     *          same group don't pre-empt each other and corrupt the
+     *          shared resources.
+     *          This parameter will be ignored if @c isLocal is FALSE.
+     */
+    Int         groupId;
+
+    Int         rpcProtocolVersion; /**< Protocol version. Do not modify */
+
+    /**
+     *  @brief  Address of the XDAIS alg IRES Interface function table
+     *          All XDAIS algorithms that use an IRES resource must define an
+     *          IRES_Fxns structure containing the pointers to functions
+     *          implementatng the IRES interface.
+     *          If the algorithm does not use an IRES resource this field
+     *          should be set to NULL.
+     */
+    Ptr         iresFxns;
+
+    /**
+     *  @brief  Codec class configuration data, if any.
+     */
+    Void        *codecClassConfig;
+
+    /**
+     *  @brief  Indicates the type of memory the alg's memory requests will
+     *          be allocated from.
+     *          The alg's memory will be allocated from cached memory, if
+     *              memType = Engine_USECACHEDMEM_CACHED,
+     *          from non-cached memory, if
+     *              memType = Engine_USECACHEDMEM_NONCACHED,
+     *          Otherwise, if
+     *              memType = Engine_USECACHEDMEM_DEFAULT,
+     *          memory allocations will be determined by the value of
+     *          ti_sdo_ce_alg_Algorithm_useCache (cached, if TRUE, non-cached,
+     *          if FALSE).
+     *
+     *  @sa  Engine_CachedMemType
+     */
+    Engine_CachedMemType memType;  /**< Memory type for alg's mem reqs. */
+
+    /**
+     *  @brief  A string idicating the type(s) of algorithm this is.
+     *          This should be a ';' separated string of inherited types.
+     *          In most cases, @c types will just be set to the VISA type
+     *          defined in the Codec Engine algorithm interface header
+     *          file included by the algorithm, depending on the XDM interface
+     *          the algorithm implements.
+     *
+     *          For example, if the algorithm implements the ISPHDEC1
+     *          interface as defined by XDM, @c types should be set
+     *          to
+     *              @c SPHDEC1_VISATYPE
+     *          (defined as "ti.sdo.ce.speech1.ISPHDEC1" in the header file
+     *          ti/sdo/ce/speech1/sphdec1.h).
+     *
+     *          Another example to illustrate multiple typss specified in
+     *          @c typss, if the algorithm implements the (made-up)
+     *          interface, ti.sdo.ce.test.xvideo.IVIDE, which in turn
+     *          implements the IVIDDEC interface, we could then set @c types
+     *          to
+     *              VIDDEC_VISATYPE";ti.sdo.ce.test.xvideo.IVIDE"
+     *          or
+     *              "ti.sdo.ce.test.xvideo.IVIDE;"VIDDEC_VISATYPE
+     */
+    String      types;
+} Engine_AlgDesc;
+
+
+/**
+ *  @brief      Name of function that a dynamically loaded codec must supply.
+ */
+#define Engine_GETALGDESCFXN  "GetEngineAlgDesc"
+
+/*
+ *  ======== Engine_DllAlgDesc ========
+ *  An alg that will be dynamically loaded must have a descriptor of this type.
+ */
+/**
+ *  @brief      Descriptor for a dynamically loaded alg. A dynamic library
+ *              for a codec must export a function that fills in a structure
+ *              of this type.
+ *
+ *  @sa         Engine_GetAlgDescFxn
+ */
+typedef struct Engine_DllAlgDesc {
+    /**
+     *  @brief  Pointer to codec's IALG_Fxns. This can not be NULL.
+     */
+    IALG_Fxns   *fxns;
+
+    /**
+     *  @brief  Pointer to codec's IDMA3_Fxns table. If the codec does not
+     *          use DMA, this should be NULL.
+     */
+    Ptr         idmaFxns;
+
+    /**
+     *  @brief  Pointer to codec's IRES_Fxns function table. This should be
+     *          NULL if the codec does not implement the IRES_Fxns.
+     */
+    Ptr         iresFxns;
+
+    /**
+     *  @brief  Inheritance hierarchy of codec. This is a ';' separated
+     *          string that lists the interfaces inherited by the code. For
+     *          example:
+     *
+     *              "ti.sdo.ce.speech1.ISPHDEC1"
+     *
+     *          or, in the case where a test IVIDE interface inherits IVIDDEC:
+     *
+     *              "ti.sdo.ce.video.IVIDDEC;ti.sdo.ce.test.xvideo.IVIDE"
+     *
+     */
+    String      types;
+
+    /**
+     *  @brief  codec class config data, if any.
+     *
+     *  @todo   Figure out what this is.
+     */
+    Void        *codecClassConfig;
+} Engine_DllAlgDesc;
+
+
+/*
+ *  ======== Engine_GetAlgDescFxn ========
+ *  A dynamically loaded codec library must supply a function of this type to
+ *  get properties of the library's algorithm.
+ */
+/**
+ *  @brief      Prototype of function that must be supplied by a dynamic
+ *              codec library to fill in a @c Engine_DllAlgDesc structure.
+ *
+ *  @remarks    This function will be called by @c Engine_addAlg() to fill
+ *              in the dynamic codec's descriptor.
+ *
+ *  @sa         Engine_DllAlgDesc
+ */
+typedef Int (*Engine_GetAlgDescFxn)(Engine_DllAlgDesc *dllAlgDesc);
+
+
+/*
+ *  ======== Engine_Desc ========
+ */
+/**
+ *  @brief      This structure is passed to @c Engine_add(), and contains
+ *              parameters to specify an engine.
+ *
+ *  @sa         Engine_add()
+ *  @sa         Engine_open()
+ */
+typedef struct Engine_Desc {
+    String name;            /**< Name of the Engine
+                             *
+                             *   @remarks   This must not be NULL
+                             */
+    Engine_AlgDesc *algTab; /**< No longer used, set to NULL */
+    String remoteName;      /**< Name of Server image, if applicable
+                             *
+                             *   @remarks   If this Engine has no remote
+                             *              algorithms, this can be NULL.
+                             *
+                             *   @remarks   On SysLink-based systems, this
+                             *              is the name of a file, and is
+                             *              passed unchanged to
+                             *              ProcMgr_load().
+                             */
+    String memMap;          /**< Name of a file containing the slave
+                             *   memory map
+                             *
+                             *   @remarks   If this Engine has no remote
+                             *              algorithms, this can be NULL.
+                             *
+                             *   @remarks   If the remote algorithms are
+                             *              on a Server whos MMU is not
+                             *              enabled, this can be NULL.
+                             *
+                             *   @remarks   The format of this file matches
+                             *              the SysLink format described at
+                  * http://processors.wiki.ti.com/index.php/SysLink_MMU_Support
+                             *
+                             *   @remarks   If useExtLoader is FALSE, this
+                             *              field can be NULL.
+                             */
+    Bool useExtLoader;      /**< Indicates whether the Server containing
+                             *   any remote algorithms will be loaded using
+                             *   an external loader (e.g. SysLink's
+                             *   slaveloader)
+                             *
+                             *   @remarks   If @c useExtLoader is TRUE,
+                             *              Engine_open() will not load
+                             *              the slave.
+                             *
+                             *   @remarks   If @c useExtLoader is FALSE,
+                             *              Engine_open() will load the
+                             *              Server with the file specified
+                             *              by @c remoteName.
+                             */
+    Int numAlgs;            /**< No longer used, set to zero */
+    Int heapId;             /**< No longer used, set to zero */
+} Engine_Desc;
+
+
+/** @cond INTERNAL */
+
+/*
+ *  ======== Engine_AlgCreateAttrs ========
+ */
+typedef struct Engine_AlgCreateAttrs {
+    Bool            useExtHeap; /**< Use a single external heap for alg's
+                                 *   memory requests if TRUE, otherwise attempt
+                                 *   to honor the alg's algAlloc() function for
+                                 *   memory heap assignments.
+                                 */
+    Int             priority;   /**< Alg instance priority (-1: use value from
+                                 *   configuration). */
+} Engine_AlgCreateAttrs;
+
+
+/*
+ *  ======== Engine_Config ========
+ */
+typedef struct Engine_Config {
+    Engine_Desc *engineTab;
+    String      localEngine;
+} Engine_Config;
+
+/*
+ *  ======== Engine_MemStat ========
+ *  This structure must match Server_MemStat.
+ */
+typedef struct Engine_MemStat {
+    Char   name[Engine_MAXSEGNAMELENGTH + 1]; /* Name of memory segment */
+    Uint32 base;           /* Base address of memory segment */
+    Uint32 size;           /* Original size of the memory segment. */
+    Uint32 used;           /* Number of bytes used. */
+    Uint32 maxBlockLen;    /* Size of the largest contiguous free block. */
+} Engine_MemStat;
+
+/* Default alg create attributes */
+extern Engine_AlgCreateAttrs Engine_ALGCREATEATTRS;
+
+/*
+ *  ======== Engine_config ========
+ */
+extern Engine_Config Engine_config;
+
+/** @endcond */
+
+
+/*
+ *  ======== Engine_addStubFxns ========
+ */
+/**
+ *  @brief      Register stub functions through which a remote algorithm
+ *              can be called
+ *
+ *  @param[in]  fxnsName    The name of the stub function table (e.g.
+ *                          "UNIVERSAL_STUBS")
+ *  @param[in]  fxns        Address of stub function table
+ *                          (e.g. &UNIVERSAL_STUBS)
+ *
+ *  @pre        As with all Codec Engine API's, CERuntime_init() must have
+ *              previously been called.
+ *
+ *  @remarks    This service is not necessary if you configure your Engine
+ *              at build/config time using Engine.createFromServer().
+ *              When using Engine.createFromServer(), the appropriate
+ *              alg-specific stubs are added to the system automatically.
+ *
+ *  @remarks    When on an RTOS (e.g. SYS/BIOS), the stubs registered are
+ *              available to all Engines in the system.  When on a HLOS
+ *              (e.g. Linux, WinCE), the stubs registered are available to
+ *              all Engines in the calling application's process.
+ *
+ *  @remarks    The symbol passed to the @c fxns argument can often be found
+ *              in the class-specific VISA header file (e.g. UNIVERSAL_STUBS
+ *              is declared in ti/sdo/ce/universal/universal.h).
+ *
+ *  @remarks    For example, to register "UNIVERSAL_STUBS" for use by an
+ *              IUNIVERSAL-compliant algorithm at runtime, you can
+ *              do the following:
+ *  @code
+ *      #include <ti/sdo/ce/Engine.h>
+ *      #include <ti/sdo/ce/universal/universal.h>
+ *
+ *      Engine_register("UNIVERSAL_STUBS",
+ *              (IALG_Fxns *)&UNIVERSAL_STUBS);
+ *  @endcode
+ *
+ *  @retval     Engine_EOK     Success.
+ *  @retval     Engine_ENOMEM  Memory allocation failed.
+ *
+ *  @sa         Engine_open()
+ */
+extern Engine_Error Engine_addStubFxns(String fxnsName, IALG_Fxns *fxns);
+
+/*
+ *  ======== Engine_add ========
+ */
+/**
+ *  @brief Add an Engine to the database of engines that can be opened with
+ *         Engine_open()
+ *
+ *  @param[in]  pDesc       The handle of an Engine Descriptor object.
+ *                          Before setting the fields of pDesc, it must
+ *                          first be initialized with @c Engine_initDesc().
+ *
+ *  @retval     Engine_EINVAL   Bad parameter passed, such as @c pDesc = NULL,
+ *                              or @c pDesc->name = NULL.
+ *  @retval     Engine_EINUSE   An engine with the name @c pDesc->name already
+ *                              exists.
+ *  @retval     Engine_ENOMEM   A memory allocation failed.
+ *  @retval     Engine_EOK      Success.
+ *
+ *  @pre        As with all Codec Engine API's, CERuntime_init() must have
+ *              previously been called.
+ *
+ *  @post       If the return value is Engine_EOK, Engine_open() can be
+ *              called with @c pDesc->name.
+ *
+ *  @par Example Usage:
+ *  @code
+ *      #include <ti/sdo/ce/Engine.h>
+ *
+ *      Engine_Desc desc;
+ *
+ *      Engine_initDesc(&desc);
+ *
+ *      desc.name = "myEngine";
+ *      desc.remoteName = "myServer.x64P";
+ *      Engine_add(&desc);
+ *  @endcode
+ *
+ *  @sa         Engine_remove()
+ *  @sa         Engine_open()
+ */
+extern Engine_Error Engine_add(Engine_Desc *pDesc);
+
+/*
+ *  ======== Engine_addAlg ========
+ */
+/**
+ *  @brief      Dynamically add an algorithm to an Engine.
+ *
+ *  @remarks    If the Engine has not been opened, the name of the Engine is
+ *              used, otherwise, a handle to the opened Engine. If the Engine
+ *              has been opened, the added alg will only be accessible to the
+ *              caller of this function.  Either one or the other, but not
+ *              both, of @c name and @c engine should be non-NULL.
+ *
+ *  @param[in]  name            The name of the engine.  @c name is
+ *                              specified in the engine configuration, or
+ *                              the name of an engine added with
+ *                              @c Engine_add(). This can only be non-NULL if
+ *                              the engine is not opened, otherwise, use
+ *                              an engine handle and set @c name to NULL.
+ *  @param[in]  engine          The handle of an engine returned by
+ *                              Engine_open(). If @c engine is non-NULL, set
+ *                              @c name to NULL.
+ *  @param[in]  location        String identifying the location of the
+ *                              algorithm.  Often this is a file name, but for
+ *                              systems without a file system, it may be a
+ *                              system-specific string identifier. This may
+ *                              be NULL if the algorithm is built into the
+ *                              executable.
+ *  @param[in]  pAlgDesc        Parameters describing the algorithm being
+ *                              added. Before setting the fields of this
+ *                              structure, it should first be initialized
+ *                              with @c Engine_initAlgDesc(), to set all
+ *                              fields to default values.
+ *                              If location is non-NULL (a dynamic library),
+ *                              then the following fields of pAlgDesc must
+ *                              be specified:
+ *                                  pAlgDesc->name
+ *                                  pAlgDesc->isLocal
+ *                                  pAlgDesc->groupId
+ *                              All other Engine_AlgDesc fields will be
+ *                              from the dynamic library.
+ *                              If location is NULL (not a dynamic library),
+ *                              the user must set the following fields of
+ *                              pAlgDesc:
+ *                                  pAlgDesc->name
+ *                                  pAlgDesc->fxns
+ *                                  pAlgDesc->idmaFxns, if applicable
+ *                                  pAlgDesc->iresFxns, if applicable
+ *                                  pAlgDesc->isLocal
+ *                                  pAlgDesc->groupId
+ *                                  pAlgDesc->types
+ *
+ *  @pre        As with all Codec Engine API's, CERuntime_init() must have
+ *              previously been called.
+ *
+ *  @pre        @c engine is a valid (non-NULL) engine handle which is
+ *              in the open state.
+ *
+ *  @remarks    If there is an existing algorithm in the engine already named
+ *              @c name, an error will be returned.
+ *
+ *  @retval     Engine_EOK      Success.
+ *  @retval     Engine_EINUSE   The Engine @c name is non-NULL, and the
+ *                              Engine is open.
+ *  @retval     Engine_EINVAL   @c pAlgDesc or @c pAlgDesc->name is NULL.
+ *  @retval     Engine_EINVAL   Both @c name and @c engine are NULL. Ensure
+ *                              one of these is non-NULL.
+ *  @retval     Engine_EINVAL   Both @c name and @c engine are non-NULL.
+ *                              Ensure that one of these is NULL.
+ *  @retval     Engine_EEXIST   There is no engine with the given name.
+ *  @retval     Engine_EINUSE   The name of the alg in @c pAlgDesc->name is
+ *                              already in use.
+ *  @par Example Usage:
+ *  @code
+ *      #include <ti/sdo/ce/Engine.h>
+ *
+ *      Engine_AlgDesc desc;
+ *
+ *      Engine_initAlgDesc(&desc);
+ *
+ *      desc.groupId = 2;
+ *      desc.isLocal = TRUE;
+ *      desc.fxns = &UNIVERSALCOPY_TI_IUNIVERSALCOPY;
+ *      desc.idmaFxns = NULL;
+ *      desc.iresFxns = NULL;
+ *      desc.memType = Engine_USECACHEDMEM_DEFAULT;
+ *      desc.types = UNIVERSAL_VISATYPE;
+ *
+ *      status = Engine_addAlg("myEngine", NULL, NULL, &desc);
+ *
+ *  @endcode
+ *
+ *  @sa         Engine_initAlgDesc()
+ *  @sa         Engine_open()
+ *  @sa         Engine_removeAlg()
+ */
+extern Engine_Error Engine_addAlg(String name, Engine_Handle engine,
+        String location, Engine_AlgDesc *pAlgDesc);
+
+/*
+ *  ======== Engine_removeAlg ========
+ */
+/**
+ *  @brief      Dynamically remove an algorithm that was added to an Engine
+ *              with Engine_addAlg().
+ *
+ *  @remarks    The same values of the parameters @c name and @c engine that
+ *              were passed to Engine_addAlg() should be used here.  In
+ *              particular, if @c name was used to add the alg, all handles to
+ *              the engine must be closed before calling Engine_removeAlg().
+ *
+ *
+ *  @param[in]  name            The name of the engine or NULL, that was
+ *                              passed to Engine_addAlg().
+ *  @param[in]  engine          The handle to an engine, previously acquired
+ *                              by a call to Engine_open(), or NULL, that was
+ *                              used in Engine_addAlg().
+ *  @param[in]  algName         Name of the algorithm to remove.
+ *
+ *  @retval     Engine_EOK          Success.
+ *  @retval     Engine_EEXIST       The engine @c name does not exist.
+ *  @retval     Engine_ENOTFOUND    @c algName could not be found in @c engine.
+ *  @retval     Engine_EINUSE       The Engine @c name is still open.
+ *
+ *  @sa         Engine_open()
+ *  @sa         Engine_addAlg()
+ */
+extern Engine_Error Engine_removeAlg(String name, Engine_Handle engine,
+        String algName);
+
+/** @cond INTERNAL */
+
+/*
+ *  ======== Engine_call ========
+ */
+extern Int Engine_call(Engine_Node node, Comm_Msg *msg);
+
+/*
+ *  ======== Engine_callAsync ========
+ */
+extern Int Engine_callAsync(Engine_Node node, Comm_Msg *msg);
+
+/*
+ *  ======== Engine_callWait ========
+ */
+extern Int Engine_callWait(Engine_Node node, Comm_Msg *msg, UInt timeout);
+
+/*
+ *  ======== Engine_ctrlNode ========
+ */
+extern Int Engine_ctrlNode(Engine_Node node, Comm_Msg *msg, Engine_Ctrl code);
+
+/** @endcond */
+
+/*
+ *  ======== Engine_close ========
+ */
+/**
+ *  @brief      Close an Engine
+ *
+ *  @param[in]  engine          The handle to an engine, previously acquired
+ *                              by a call to Engine_open().
+ *
+ *  @pre        @c engine must not be referenced by any algorithm instance
+ *              objects; i.e., you must first delete all algorithm instances
+ *              associated with @c engine before closing it.
+ *
+ *  @pre        @c engine is a valid (non-NULL) engine handle which is
+ *              in the open state.
+ *
+ *  @sa         Engine_open()
+ */
+extern Void Engine_close(Engine_Handle engine);
+
+/** @cond INTERNAL */
+/*
+ *  ======== Engine_createNode ========
+ */
+/**
+ *  @brief      Create a remote algorithm
+ *
+ *  @param[in]  engine          The handle to an engine, previously acquired
+ *                              by a call to Engine_open().
+ *  @param[in]  name            Name of the algorithm to create.
+ *  @param[in]  msgSize         Size of the internal message required to
+ *                              communicate with the remote algorithm.
+ *  @param[in]  nodeAttrs       Creation parameters for the remote algorithm.
+ *  @param[in]  attrs           Attributes used by the framework for creating
+ *                              the remote algorithm.
+ *
+ *  @pre        @c engine is a valid (non-NULL) engine handle which is
+ *              in the open state.
+ *
+ *  @remarks    Engine_createNode2() was added after Engine_createNode() to
+ *              support more use cases.  Engine_createNode() is a wrapper
+ *              around Engine_createNode2(), and is maintained for compatibility.
+ *
+ *  @retval     NULL            Failure
+ *  @retval     non-NULL        A handle to the created remote algorithm.
+ *
+ *  @sa         Engine_createNode2()
+ *  @sa         Engine_deleteNode()
+ */
+extern Engine_Node Engine_createNode(Engine_Handle engine, String name,
+    size_t msgSize, IALG_Params *nodeAttrs, Engine_AlgCreateAttrs *attrs);
+
+
+/*
+ *  ======== Engine_createNode2 ========
+ */
+/**
+ *  @brief      Create a remote algorithm
+ *
+ *  @param[in]  engine          The handle to an engine, previously acquired
+ *                              by a call to Engine_open().
+ *  @param[in]  name            Name of the algorithm to create.
+ *  @param[in]  msgSize         Size of the internal message required to
+ *                              communicate with the remote algorithm.
+ *  @param[in]  nodeAttrs       Creation parameters for the remote algorithm.
+ *  @param[in]  nodeAttrsSize   Size of @c nodeAttrs.
+ *  @param[in]  attrs           Attributes used by the framework for creating
+ *                              the remote algorithm.
+ *
+ *  @pre        @c engine is a valid (non-NULL) engine handle which is
+ *              in the open state.
+ *
+ *  @remarks    Engine_createNode() is the preferred method to create remote
+ *              algorithms.  However, some algorithm interfaces incorrectly
+ *              fail to provide a size field of type "Int" as the first field
+ *              in their creation parameters, which the XDAIS spec defines.
+ *              This service allows the creation of remote algorithms where the
+ *              size of the creation params is specified "some other way" than
+ *              the XDAIS spec defines.
+ *
+ *  @retval     NULL            Failure
+ *  @retval     non-NULL        A handle to the created remote algorithm.
+ *
+ *  @sa         Engine_createNode()
+ *  @sa         Engine_deleteNode()
+ */
+extern Engine_Node Engine_createNode2(Engine_Handle engine, String name,
+    size_t msgSize, IALG_Params *nodeAttrs, Int nodeAttrsSize,
+    Engine_AlgCreateAttrs *attrs);
+
+
+/*
+ *  ======== Engine_deleteNode ========
+ */
+extern Void Engine_deleteNode(Engine_Node node);
+
+/*
+ *  ======== Engine_getAlgMemRecs ========
+ */
+/**
+ *  @brief      Get the IALG_MemRecs used by an algorithm
+ *
+ *  @param[in]  node    Handle to an algorithm instance.
+ *  @param[out] memTab  Location to store the IALG_MemRecs.
+ *  @param[in]  size    Maximum number of IALG_MemRecs to put in memTab array.
+ *  @param[out] numRecs Actual number of IALG_MemRecs copied into memTab array.
+ *
+ *  @retval     Engine_EOK       Success.
+ *  @retval     Engine_ERUNTIME  Failure.
+ *
+ *  @sa         Engine_getAlgNumRecs()
+ */
+extern Engine_Error Engine_getAlgMemRecs(Engine_Node node, IALG_MemRec *memTab, Int size,
+        Int *numRecs);
+
+/*
+ *  ======== Engine_getAlgNumRecs ========
+ */
+/**
+ *  @brief      Get the number of IALG_MemRecs used by a remote algorithm
+ *
+ *  @param[in]  node    Handle to an algorithm instance.
+ *  @param[out] numRecs Location to store the number of IALG_MemRecs used.
+ *
+ *  @retval     Engine_EOK       Success.
+ *  @retval     Engine_ERUNTIME  Failure.
+ *
+ *  @sa         Engine_getAlgMemRecs()
+ */
+extern Engine_Error Engine_getAlgNumRecs(Engine_Node node, Int *numRecs);
+
+/*
+ *  ======== Engine_getConstName ========
+ */
+extern String Engine_getConstName(Engine_Handle engine, String name,
+    String type);
+
+/*
+ *  ======== Engine_getFxns ========
+ */
+extern IALG_Fxns *Engine_getFxns(Engine_Handle svr, String name, String type,
+        Bool *isLocal, Ptr *idmaFxns, Ptr *iresFxns, Int *groupId,
+        Engine_CachedMemType *memType);
+
+/*
+ *  ======== Engine_getMemId ========
+ */
+extern Int Engine_getMemId(Engine_Handle engine);
+
+/*
+ *  ======== Engine_getLocalEngine ========
+ */
+extern Engine_Handle Engine_getLocalEngine(Void);
+
+/*
+ *  ======== Engine_getEngine ========
+ */
+extern Engine_Handle Engine_getEngine(Engine_Node node);
+
+/*
+ *  ======== Engine_getMemStat ========
+ */
+extern Engine_Error Engine_getMemStat(Server_Handle server, Int segNum,
+    Engine_MemStat *stat);
+
+/*
+ *  ======== Engine_getNumMemSegs ========
+ */
+extern Engine_Error Engine_getNumMemSegs(Server_Handle server, Int *numSegs);
+
+/*
+ *  ======== Engine_getNumEngines ========
+ */
+extern Int Engine_getNumEngines();
+
+/*
+ *  ======== Engine_getProcId ========
+ */
+extern String Engine_getProcId(Engine_Handle engine);
+
+/*
+ *  ======== Engine_hasServer ========
+ */
+extern Bool Engine_hasServer(Engine_Handle engine);
+
+/*
+ *  ======== Engine_init ========
+ */
+extern Void Engine_init(Void);
+
+
+/** @endcond */
+
+/*
+ *  ======== Engine_initAlgDesc ========
+ */
+/**
+ *  @brief      Initialize an Engine_AlgDesc structure with default values.
+ *
+ *  @param[in]  pAlgDesc  Location of Engine_AlgDesc object to initialize.
+ *                        The fields of pAlgDesc will be set to the following:
+ *
+ *                        pAlgDesc->name = NULL;
+ *                        pAlgDesc->uuid.data = 0;
+ *                        pAlgDesc->fxns = NULL;
+ *                        pAlgDesc->idmaFxns = NULL;
+ *                        pAlgDesc->typeTab = NULL;
+ *                        pAlgDesc->isLocal = TRUE;
+ *                        pAlgDesc->groupId = 0;
+ *                        pAlgDesc->rpcProtocolVersion = 0;
+ *                        pAlgDesc->iresFxns = NULL;
+ *                        pAlgDesc->codecClassConfig = NULL;
+ *                        pAlgDesc->memType = Engine_USECACHEDMEM_DEFAULT;
+ *                        pAlgDesc->types = NULL;
+ *
+ *  @sa         Engine_addAlg()
+ */
+extern Void Engine_initAlgDesc(Engine_AlgDesc *pAlgDesc);
+
+/*
+ *  ======== Engine_initAttrs ========
+ */
+/**
+ *  @brief      Initialize an Engine_Attrs structure with default values.
+ *
+ *  @param[in]  pAttrs Location of Engine_Attrs object to initialize.
+ *
+ *  @sa         Engine_open()
+ */
+extern Void Engine_initAttrs(Engine_Attrs *pAttrs);
+
+/*
+ *  ======== Engine_initDesc ========
+ */
+/**
+ *  @brief      Initialize an Engine_Desc structure with default values.
+ *
+ *  @param[in]  pDesc  Location of Engine_Desc object to initialize.
+ *                     The fields of pDesc will be set to the following:
+ *
+ *                        pDesc->name = NULL;
+ *                        pDesc->remoteName = NULL;
+ *                        pDesc->heapId = 0;
+ *
+ *  @sa         Engine_add()
+ */
+extern Void Engine_initDesc(Engine_Desc *pDesc);
+
+/** @cond INTERNAL */
+
+/*
+ *  ======== Engine_getRemoteVisa ========
+ */
+extern UInt32 Engine_getRemoteVisa(Engine_Node node);
+
+/*
+ *  ======== Engine_getCodecClassConfig ========
+ */
+extern Ptr Engine_getCodecClassConfig(Engine_Handle engine, String name,
+    String type);
+
+/*
+ *  ======== Engine_getNodeQueues ========
+ */
+extern Void Engine_getNodeQueues(Engine_Node node, Comm_Id *stdIn, Comm_Handle *stdOut);
+
+
+/*
+ *  ======== Engine_initFromServer ========
+ */
+extern Engine_Error Engine_initFromServer(Engine_Handle engine);
+
+
+/*
+ *  ======== Engine_redefineHeap ========
+ */
+extern Engine_Error Engine_redefineHeap(Server_Handle server, String name,
+        Uint32 base, Uint32 size);
+
+/*
+ *  ======== Engine_releaseTraceToken ========
+ */
+extern Bool Engine_releaseTraceToken(Server_Handle server);
+
+/*
+ *  ======== Engine_requestTraceToken ========
+ */
+extern Engine_Error Engine_requestTraceToken(Server_Handle server);
+
+/*
+ *  ======== Engine_restoreHeap ========
+ */
+extern Engine_Error Engine_restoreHeap(Server_Handle server, String name);
+
+/** @endcond */
+
+/*
+ *  ======== Engine_open ========
+ */
+/**
+ *  @brief      Open an Engine
+ *
+ *  The handle returned may be used to create one or more instances of an
+ *  algorithm contained in the specified Engine.
+ *
+ *  An Engine may be opened more than once; each open returns a unique
+ *  handle that can be used to create algorithm instances or get status of the
+ *  Engine.
+ *
+ *  Engine handles must not be concurrently accessed by multiple threads; each
+ *  thread must either obtain its own handle (via Engine_open()) or explicitly
+ *  serialize access to a shared handle.
+ *
+ *  @param[in]  name            The name of the engine to open.  @c name is
+ *                              specified in the engine configuration.
+ *  @param[in]  attrs           Attributes for the open engine.
+ *  @param[out] ec              Optional output error code
+ *
+ *  @retval     NULL            An error has occurred.
+ *  @retval     non-NULL        The handle to the opened engine.
+ *
+ *  @pre        @c name is a non-NULL string.
+ *
+ *  @pre        @c name is a valid, pre-configured name of an engine.
+ *
+ *  @pre        As with all Codec Engine API's, CERuntime_init() must have
+ *              previously been called.
+ *
+ *  @post       If the return handle is NULL and @c ec is non-NULL, @c *ec
+ *              is set to a non-zero value indicating the cause of the failure.
+ *
+ *  @post       If @c ec is non-NULL, the Engine_Error value is set to one of
+ *              the following values:
+ *                - #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 comm connection to DSP
+ *                - #Engine_ENOSERVER   can't locate the server on the DSP
+ *                - #Engine_ECOMALLOC   can't allocate communication buffer
+ *
+ *  @sa         Engine_close()
+ *  @sa         Engine_add()
+ *  @sa         Engine_remove()
+ */
+extern Engine_Handle Engine_open(String name, Engine_Attrs *attrs,
+        Engine_Error *ec);
+
+/*
+ *  ======== Engine_fwriteTrace ========
+ */
+/**
+ *  @brief              Write Server's trace buffer to specifed file stream
+ *
+ *  @param[in]  engine  The handle to the opened engine.
+ *
+ *  @param[in]  prefix  A string to prepend to each line output; this
+ *                      allows one to easily identify trace from the
+ *                      server from the application's trace, for
+ *                      example.
+ *  @param[in]  out     A open FILE stream used to output the
+ *                      Server's trace characters.
+ *
+ *  @retval             Integer number of characters copied to the specified
+ *                      FILE stream.
+ *
+ *  @pre        @c engine is a valid (non-NULL) engine handle and the engine
+ *              is in the open state.
+ *
+ *  @post       In the event a negative value is returned,
+ *              Engine_getLastError() will return one of the following values:
+ *                - #Engine_ERUNTIME    Either an internal runtime error
+ *                                      occured or the underlying server
+ *                                      error occured.
+ *                - #Engine_EINUSE      Server trace resource is already in use.
+ */
+extern Int Engine_fwriteTrace(Engine_Handle engine, String prefix, FILE *out);
+
+/*
+ *  ======== Engine_getAlgInfo ========
+ */
+/**
+ *  @brief      Get details of an algorithm configured into an engine
+ *
+ *  @param[in]  name        The name of the engine.  @c name is
+ *                          specified in the engine configuration.
+ *  @param[out] algInfo     Structure to store algorithm details. The
+ *                          @c algInfoSize field of this structure must
+ *                          be set to @c sizeof(Engine_AlgInfo) by the
+ *                          application.
+ *  @param[out] index       The index of the algorithm to get the information.
+ *
+ *  @retval     Engine_EOK        Success.
+ *  @retval     Engine_EEXIST     There is no engine with the given name.
+ *  @retval     Engine_ENOTFOUND  @c index is greater than or equal to the
+ *                                total number of algorithms configured for
+ *                                the engine, or @c index < 0.
+ *  @retval     Engine_EINVAL     The value of @c algInfoSize passed to this
+ *                                function does not match the CE library's
+ *                                @c sizeof(Engine_AlgInfo).
+ *
+ *  @pre        @c name is a non-NULL string.
+ *
+ *  @pre        @c algInfo is non-NULL.
+ *
+ *  @pre        As with all Codec Engine API's, CERuntime_init() must have
+ *              previously been called.
+ *
+ *  @post       If @c name is a valid engine name and 0 <= @c index < the
+ *              total number of algorithms configured for the engine, then
+ *              @c algInfo will contain the information for the engine's
+ *              ith (i = @c index) algorithm.
+ *
+ *  @sa         Engine_getNumAlgs()
+ */
+extern Engine_Error Engine_getAlgInfo(String name, Engine_AlgInfo *algInfo,
+        Int index);
+
+/*
+ *  ======== Engine_getAlgInfo2 ========
+ */
+/**
+ *  @brief      Get details of an algorithm.
+ *
+ *  @param[in]  name        The name of the engine.  @c name is
+ *                          specified in the engine configuration. This
+ *                          may be NULL if @c engine contains a valid
+ *                          engine handle.
+ *  @param[in]  engine      The handle of an engine returned by Engine_open().
+ *                          If this is NULL, only information for a static
+ *                          alg can be obtained.
+ *  @param[out] algInfo2    Structure to store algorithm details. The
+ *                          @c algInfoSize field of this structure must
+ *                          be set to @c sizeof(Engine_AlgInfo2) by the
+ *                          application.
+ *  @param[out] index       The index of the algorithm to get the information.
+ *
+ *  @retval     Engine_EOK        Success.
+ *  @retval     Engine_EEXIST     There is no engine with the given name.
+ *  @retval     Engine_ENOTFOUND  @c index is greater than or equal to the
+ *                                total number of algorithms configured for
+ *                                the engine, or @c index < 0.
+ *  @retval     Engine_EINVAL     The value of @c algInfoSize passed to this
+ *                                function does not match the CE library's
+ *                                @c sizeof(Engine_AlgInfo2).
+ *
+ *  @pre        @c name is a non-NULL string or @c engine is non-NULL.
+ *
+ *  @pre        @c algInfo2 is non-NULL.
+ *
+ *  @pre        As with all Codec Engine API's, CERuntime_init() must have
+ *              previously been called.
+ *
+ *  @post       If @c name is a valid engine name and 0 <= @c index < the
+ *              total number of algorithms configured for the engine, then
+ *              @c algInfo2 will contain the information for the engine's
+ *              ith (i = @c index) algorithm.
+ *
+ *  @remarks    This service supports algorithms statically configured into
+ *              an Engine at build/config time, or algorithms that have been
+ *              dynamically added to an opened engine.  If the Engine has not
+ *              been opened yet, the name of the Engine is used to get the
+ *              statically configured alg.  If the Engine has been opened, the
+ *              Engine handle can be used to get either information for a
+ *              statically configured alg, or a remote alg that was added when
+ *              the server was queried during Engine_open().
+ *
+ *  @sa         Engine_getNumAlgs2().
+ */
+extern Engine_Error Engine_getAlgInfo2(String name, Engine_Handle engine,
+        Engine_AlgInfo2 *algInfo2, Int index);
+
+
+/** @cond INTERNAL */
+/*
+ *  ======== Engine_getCpuLoad ========
+ */
+/**
+ *  @brief      Get Server's cpu usage in percent
+ *
+ *  @deprecated This service has been replaced by Server_getCpuLoad()
+ *              to better indicate that this API is not intended for
+ *              obtaining the current processor's CPU load, rather it
+ *              obtains the CPU load of a remote Server.
+ *
+ *  @param[in]  engine  The handle to the opened engine.
+ *
+ *  @retval             integer between 0-100 indicating percentage
+ *                      of time the Server is processing measured
+ *                      over a period of approximately 1 second.  If
+ *                      the load is unavailable, a negative value is
+ *                      returned.
+ *
+ *  @pre        @c engine is a valid (non-NULL) engine handle and the engine
+ *              is in the open state.
+ *
+ *  @post       In the event a negative value is returned,
+ *              Engine_getLastError() will return one of the following values:
+ *                - #Engine_ERUNTIME    Either an internal runtime error
+ *                                      occured or the underlying server
+ *                                      error occured.
+ *                - #Engine_ENOTAVAIL   The CPU load can not be computed.
+ *
+ *  @sa         Server_getCpuLoad()
+ */
+extern Int Engine_getCpuLoad(Engine_Handle engine);
+
+/** @endcond */
+
+
+/*
+ *  ======== Engine_getDesc ========
+ */
+/**
+ *  @brief      Fill in an Engine_Desc structure with the values of the
+ *              Engine descriptor for an Engine.
+ *
+ *  @param[in]  name            The name of the Engine.  @c name is
+ *                              specified in the engine configuration or a
+ *                              a name that was passed to @c Engine_add().
+ *  @param[out] desc            The structure where the descriptor of the
+ *                              Engine specified by @c name will be copied to.
+ *
+ *  @retval     Engine_EOK      Success.
+ *  @retval     Engine_EEXIST   There is no engine with the given name.
+ *
+ *  @pre        @c name is a non-NULL string.
+ *
+ *  @pre        @c desc is non-NULL.
+ *
+ *  @pre        As with all Codec Engine API's, CERuntime_init() must have
+ *              previously been called.
+ *
+ *  @post       If @c name is a valid engine name, then desc will contain
+ *              the descriptor of the engine @c name.
+ *
+ *  @sa         Engine_setDesc().
+ */
+extern Engine_Error Engine_getDesc(String name, Engine_Desc *desc);
+
+/*
+ *  ======== Engine_getLastError ========
+ */
+/**
+ *  @brief              Get error code of the last failed operation
+ *
+ *  @param[in]  engine  The handle to the opened engine.
+ *
+ *  @retval             error code (Engine_Error) of the last failed
+ *                      engine operation.
+ *
+ *  @pre        As with all Codec Engine API's, CERuntime_init() must have
+ *              previously been called.
+ *
+ *  @pre        @c engine is a valid (non-NULL) engine handle and the engine
+ *              is in the open state.
+ */
+extern Engine_Error Engine_getLastError(Engine_Handle engine);
+
+/*
+ *  ======== Engine_getName ========
+ */
+/**
+ *  @brief      Get the name of an opened engine
+ *
+ *  @param[in]  engine  The handle to the opened engine.
+ *
+ *  @pre        As with all Codec Engine API's, CERuntime_init() must have
+ *              previously been called.
+ *
+ *  @retval     NULL            An error has occurred.
+ *  @retval     non-NULL        The name of the opened engine.
+ */
+extern String Engine_getName(Engine_Handle engine);
+
+
+/*
+ *  ======== Engine_getNumAlgs ========
+ */
+/**
+ *  @brief      Get the number of algorithms configured into an Engine
+ *
+ *  @param[in]  name            The name of the Engine.  @c name is
+ *                              specified in the engine configuration.
+ *  @param[out] numAlgs         The number of algorithms that are configured
+ *                              in the given engine.
+ *
+ *  @retval     Engine_EOK      Success.
+ *  @retval     Engine_EEXIST   There is no engine with the given name.
+ *
+ *  @pre        @c name is a non-NULL string.
+ *
+ *  @pre        @c numAlgs is non-NULL.
+ *
+ *  @pre        As with all Codec Engine API's, CERuntime_init() must have
+ *              previously been called.
+ *
+ *  @post       If @c name is a valid engine name, then numAlgs will contain
+ *              the number of algorithms configured for the given engine.
+ *
+ *  @sa         Engine_getAlgs().
+ */
+extern Engine_Error Engine_getNumAlgs(String name, Int *numAlgs);
+
+/*
+ *  ======== Engine_getNumAlgs2 ========
+ */
+/**
+ *  @brief Get the number of algorithms statically configured into an engine
+ *         or the total number of algorithms both statically configured and
+ *         dynamically added through server information when the engine was
+ *         opened.
+ *
+ *  @param[in]  name            The name of the engine.  @c name is
+ *                              specified in the engine configuration. @c name
+ *                              can be NULL, if @c engine is a valid
+ *                              Engine_Handle.
+ *  @param[in]  engine          The handle of an engine returned by
+ *                              Engine_open(). If @c engine is NULL, @c name
+ *                              must be non-NULL, and only the number of
+ *                              statically configured algorithms will be
+ *                              returned in @c numAlgs.
+ *                              specified in the engine configuration.
+ *  @param[out] numAlgs         The number of algorithms that are configured
+ *                              in the given engine.
+ *
+ *  @retval     Engine_EOK      Success.
+ *  @retval     Engine_EEXIST   There is no engine with the given name.
+ *
+ *  @pre        @c name is a non-NULL string or @c engine is non-NULL.
+ *
+ *  @pre        @c numAlgs is non-NULL.
+ *
+ *  @pre        As with all Codec Engine API's, CERuntime_init() must have
+ *              previously been called.
+ *
+ *  @post       If @c name is a valid engine name, then numAlgs will contain
+ *              the number of algorithms configured for the given engine.
+ *
+ *  @remarks    If the engine has a server, but was not configured with
+ *              Engine.createFromServer() number of remote algorithms (if any)
+ *              that were statically configured into the engine, will be
+ *              counted twice: once for the static alg table, and once for
+ *              the information queried from the server.
+ *
+ *  @sa         Engine_getAlgs().
+ */
+extern Engine_Error Engine_getNumAlgs2(String name, Engine_Handle engine,
+        Int *numAlgs);
+
+/*
+ *  ======== Engine_getServer ========
+ */
+/**
+ *  @brief              Get handle to an Engine's Server
+ *
+ *  This function returns the handle to an Engines server, that can be used
+ *  with Server APIs to obtain information from and control the remote DSP
+ *  server.
+ *
+ *  @param[in]  engine  The handle to the opened engine.
+ *
+ *  @retval             Handle to engine's server.
+ *
+ *  @pre        As with all Codec Engine API's, CERuntime_init() must have
+ *              previously been called.
+ *
+ *  @pre        @c engine is a valid (non-NULL) engine handle and the engine
+ *              is in the open state.
+ */
+extern Server_Handle Engine_getServer(Engine_Handle engine);
+
+
+/*
+ *  ======== Engine_getUsedMem ========
+ */
+/**
+ *  @brief      Get Server's total memory usage
+ *
+ *  @deprecated This service has been replaced by Server_getMemStat()
+ *              to better indicate that this API is not intended for
+ *              obtaining the current processor's memory statistics,
+ *              rather it obtains the memory statistics of a remote
+ *              Server.  Also, Server_getMemStat() provides more granularity
+ *              than Engine_getUsedMem().
+ *
+ *  @param[in]  engine  The handle to the opened engine.
+ *
+ *  @retval     Total amount of used memory (in MAUs).  If the amount is not
+ *              available, 0 is returned and the reason can be retrieved via
+ *              Engine_getLastError().
+ *
+ *  @pre        As with all Codec Engine API's, CERuntime_init() must have
+ *              previously been called.
+ *
+ *  @pre        @c engine is a valid (non-NULL) engine handle and the engine
+ *              is in the open state.
+ *
+ *  @post       in the event that 0 is returned, Engine_getLastError() will
+ *              return one of the following values:
+ *                - #Engine_ERUNTIME    Either an internal runtime error
+ *                                      occured or the underlying server
+ *                                      error occured.
+ *                - #Engine_ENOTAVAIL   The memory usage can not be computed.
+ */
+extern UInt32 Engine_getUsedMem(Engine_Handle engine);
+
+
+/*
+ *  ======== Engine_remove ========
+ */
+/**
+ *  @brief      Remove an engine from the list of engines that can be opened
+ *
+ *  @param[in]  engineName      The name of the engine to be removed.
+ *
+ *  @pre        As with all Codec Engine API's, CERuntime_init() must have
+ *              previously been called.
+ *
+ *  @pre        @c engineName is non-NULL.
+ *
+ *  @retval     Engine_EINUSE      The engine cannot be removed because
+ *                                 an instance of it is still opened.
+ *  @retval     Engine_EEXIST      No engine by this name exists.
+ *  @retval     Engine_EOK         Success.
+ *
+ *  @sa         Engine_add()
+ */
+extern Engine_Error Engine_remove(String engineName);
+
+
+/*
+ *  ======== Engine_setDesc ========
+ */
+/**
+ *  @brief      Set values for an Engine's descriptor.  This function should
+ *              only be called when the Engine has not yet been opened.
+ *
+ *  @param[in]  name            The name of the Engine.  @c name is
+ *                              specified in the engine configuration or a
+ *                              a name that was passed to @c Engine_add().
+ *  @param[in] desc             The structure where descriptor values for the
+ *                              Engine specified by @c name will be copied
+ *                              from.
+ *
+ *  @retval     Engine_EOK      Success.
+ *  @retval     Engine_EEXIST   There is no engine with the given name.
+ *  @retval     Engine_EINUSE   The Engine @c name has already been opened.
+ *
+ *  @pre        @c name is a non-NULL string.
+ *
+ *  @pre        @c desc is non-NULL.
+ *
+ *  @pre        As with all Codec Engine API's, CERuntime_init() must have
+ *              previously been called.
+ *
+ *  @post       If @c name is a valid engine name, then the desscriptor for
+ *              the engine @c name will have been updated with values from
+ *              @c desc.
+ *
+ *  @remarks    Use @c Engine_getDesc() to fill in the descriptor, override
+ *              the fields you want to change, and then pass the descriptor
+ *              to Engine_setDesc().
+ *              Only the following fields of the Engine_Desc are allowed to
+ *              be modified:
+ *                  @c memMap
+ *                  @c useExtLoader
+ *                  @c heapId
+ *
+ *  @sa         Engine_getDesc().
+ */
+extern Engine_Error Engine_setDesc(String name, Engine_Desc *desc);
+
+
+/*
+ *  ======== Engine_setTrace ========
+ */
+/**
+ *  @brief      Set Server's trace mask
+ *
+ *  @param[in]  engine  The handle to the opened engine.
+ *  @param[in]  mask    Trace mask, e.g. "*=01234567"
+ *
+ *  @retval     Engine_ENOSERVER   No server for this engine.
+ *  @retval     Engine_EINUSE      Trace resource is already in use.
+ *  @retval     Engine_ERUNTIME    Internal runtime error has occurred.
+ *
+ *  @pre        As with all Codec Engine API's, CERuntime_init() must have
+ *              previously been called.
+ *
+ *  @pre        @c engine is a valid (non-NULL) engine handle and the engine
+ *              is in the open state.
+ *
+ *  @remarks    This only sets the trace for a remote server.  To change
+ *              the trace mask for the application-side of the framework,
+ *              use Diags_setMask(), or Diags_setMaskMeta().
+ *
+ *  @sa         xdc.runtime.Diags
+ */
+extern Int Engine_setTrace(Engine_Handle engine, String mask);
+
+
+/** @cond INTERNAL */
+
+/*
+ *  ======== Engine_getDesc ========
+ *  Internal for testing.
+ */
+extern Engine_Desc *_Engine_getDesc(Int i);
+
+/** @endcond */
+
+/*@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/packages/ti/sdo/ce/Engine.xdc b/packages/ti/sdo/ce/Engine.xdc
new file mode 100644 (file)
index 0000000..195154b
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2013, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * *  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * *  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * *  Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/*!
+ *  ======== Engine ========
+ *  Engine Configuration interface
+ */
+@Template("./Engine.xdt")
+
+metaonly module Engine {
+
+    /*!
+     *  ======== local ========
+     *  Default engine used by clients of the VISA API's that pass NULL for
+     *  the engine handle
+     *
+     *  @_nodoc
+     */
+    config Engine.Instance local;
+
+    /*!
+     *  ======== MAXGROUPID ========
+     *  Maximum group id.
+     */
+    const Int MAXGROUPID = 20;
+
+
+   /*!
+     *  ======== initFromServer ========
+     *  Allow alg tables of engines with a remote server to be populated by
+     *  querying the server.
+     */
+    config Bool initFromServer = true;
+
+    /*!
+     *  ======== AlgDesc ========
+     *  Algorithm descriptor
+     *
+     *  Each engine "contains" multiple algorithms described by AlgDesc
+     *  structures.
+     *
+     *  @field(name)    This string specifies the "local" name used by the
+     *                  application to identify the algorithm to instantiate
+     *  @field(mod)     This field is a module reference that identifies the
+     *                  actual module implementing the algorithm to instantiate
+     *  @field(local)   If true, the algorithm should be instantiated on the
+     *                  "local" CPU; otherwise the server will create an
+     *                  instance of the algorithm identifed by `mod`.
+     *  @field(groupId) This id specifies which resource sharing group
+     *                  this codec will be placed into.  This 'group' concept
+     *                  is used by the framework to ensure algorithms in the
+     *                  same group don't pre-empt each other and corrupt the
+     *                  shared resources.
+     *
+     *                  Note that this parameter is ignored if `local` is not
+     *                  TRUE.
+     */
+    struct AlgDesc {
+        String          name;       /*! Alg nick-name */
+        ICodec.Module   mod;        /*! The alg implementation */
+        Bool            local;      /*! Run algorithm locally */
+        Int             groupId;    /*! Alg group ID for sharing resources */
+    };
+
+    /*!
+     *  ======== createFromServer ========
+     *  Create an Engine from a Server package
+     *
+     *  Given a Server package and an executable in that package, this method
+     *  creates an Engine instance and initializes it from details in the
+     *  Server provided.
+     *
+     *  An Engine instance created this way has all the codecs that exist
+     *  in the Server executable - with codec names matching the names
+     *  configured into the Server, and is configured to use an appropriate
+     *  memory map and other DSP-specific info.
+     *
+     *  Example usage:
+     *  @p(code)
+     *  var myEngine = Engine.createFromServer("video_copy",
+     *                     "./video_copy.x64P",
+     *                     "ti.sdo.ce.examples.servers.video_copy");
+     *
+     *  @param(engineName)        Name to be used for the engine created
+     *  @param(serverExecutable)  Path to the server executable (including the
+     *                            executable), relative from server package
+     *  @param(serverPackage)     Name of the server package
+     *
+     *  @a(returns)               An Engine instance of the same type as
+     *                            if {@link #create create()} were called.
+     */
+    function createFromServer(engineName, serverExecutable, serverPackage);
+
+    /*!
+     *  ======== close ========
+     *  Internal close method (see package.xs)
+     * @_nodoc
+     */
+    function close();
+
+    /*!
+     *  ======== validate ========
+     *  Internal validate method (see package.xs)
+     * @_nodoc
+     */
+    function validate();
+
+    /*!
+     * ======== usesIRES ========
+     * Returns true if there is an engine with a local alg that implements
+     * iresFxns. This function is used to determine whether or not RMAN
+     * library needs to be linked in.
+     *
+     * @_nodoc
+     */
+    bool usesIRES();
+
+    /*!
+     *  ======== hasServer ========
+     *  Returns true if there is an engine with a remote alg, or an engine
+     *  that uses a server.
+     *
+     *  @_nodoc
+     */
+    bool hasServer();
+
+instance:
+
+    /*!
+     *  ======== create ========
+     *  Create Engine instance
+     *
+     *  Parameters:
+     *  @p(dlist)
+     *      - `name`
+     *          Name of this engine; this name is used by clients via the
+     *          `Engine_open()` API to identify the collection of algorithms
+     *          available.
+     *
+     *      - `algs`
+     *          Array of algorithms this engine supports
+     *
+     *      - `server`
+     *          Optional name of the DSP Server; this name is used (if
+     *          necessary) to load and start any associated DSP CPUs required
+     *          to support this Engine instance
+     */
+    create(String name, AlgDesc algs[]);
+
+    /*!
+     *  ======== name ========
+     *  Name of the Engine
+     *
+     *  This string provided by the application in the `Engine_open()` call.
+     */
+    config String name;
+
+    /*!
+     *  ======== algs ========
+     *  Array of algorithms available in the Engine
+     *
+     *  An array of algorithms which this Engine instance provides.  A mix
+     *  of local and remote algorithms can be specified in this array.
+     *
+     *  {@link #createFromServer createFromServer()} can be used to populate
+     *  this array with algorithms configured into a remote Server.
+     *
+     *  @see createFromServer
+     */
+    config AlgDesc algs[];
+
+    /*!
+     *  ======== server ========
+     *  Optional name of a remote Server
+     *
+     *  This parameter is only necessary when there are algorithms configured
+     *  to run remotely - i.e., their `local` field is set to false.
+     *
+     *  Engines containing these remote algorithms will need to set
+     *  this `server` parameter to the name of the