summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--README.txt51
-rw-r--r--common.mk62
-rw-r--r--dce_priv.h64
-rw-r--r--dce_rpc.h145
-rw-r--r--libdce.c711
-rw-r--r--libdce.h79
-rw-r--r--memplugin.h81
-rw-r--r--memplugin_qnx.c158
-rw-r--r--nto/Makefile2
-rw-r--r--nto/README.txt1
-rw-r--r--nto/arm/Makefile2
-rw-r--r--nto/arm/a.le.v7/Makefile1
-rw-r--r--nto/arm/so.le.v7/Makefile1
-rw-r--r--nto/qconf-override.mk9
-rw-r--r--test_qnx/Makefile2
-rw-r--r--test_qnx/arm/Makefile8
-rw-r--r--test_qnx/arm/le.v7/Makefile1
-rw-r--r--test_qnx/common.mk50
-rw-r--r--test_qnx/dce_test.c1437
-rw-r--r--test_qnx/dce_test.use38
21 files changed, 2906 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..18dffdd
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,3 @@
1LIST=libdce
2LATE_DIRS=test_qnx
3include recurse.mk
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..05996e8
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,51 @@
1## Building LIBDCE for QNX ##
2
3Exporting QNX variables:
4export QNX_ROOT=/opt/qnx650
5export QNX_HOST=${QNX_ROOT}/host/linux/x86
6export LD_LIBRARY_PATH=${QNX_HOST}/usr/lib
7export QNX_TARGET=${QNX_ROOT}/target/qnx6
8export MAKEFLAGS=-I${QNX_TARGET}/usr/include
9export QNX_CONFIGURATION=/etc/qnx
10export QNX_JAVAHOME=${QNX_ROOT}/_jvm
11export PATH=${QNX_HOST}/usr/bin:${PATH}:${QNX_CONFIGURATION}/bin
12export QNX_USERNAME=<registered email-id at QNX> //not important
13eval `qconfig -n "QNX Software Development Platform 6.5.0" -e`
14
15If previous eval doesn't work, that is it doesn't output:
16export QNX_HOST="/opt/qnx650/host/linux/x86";
17export QNX_TARGET="/opt/qnx650/target/qnx6";
18export PATH="/opt/qnx650/host/linux/x86/usr/bin:/opt/qnx650/host/linux/x86/bin:/opt/qnx650/host/
19 linux/x86/sbin:/opt/qnx650/host/linux/x86/usr/sbin:/opt/qnx650/host/linux/x86/usr/photon/appbuilder:
20 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/etc/qnx/bin:/etc/qnx/bin:
21 /opt/qnx650:/etc/qnx/bin:/etc/qnx/bin:/etc/qnx/bin:/etc/qnx/bin";
22export LD_LIBRARY_PATH="/opt/qnx650/host/linux/x86/usr/lib";
23export MAKEFLAGS="-I/opt/qnx650/target/qnx6/usr/include";
24
25then try : /opt/qnx650/host/linux/x86/usr/bin/qconfig -n "QNX Software Development Platform 6.5.0" -e
26
27Exporting LIBDCE variables:
28export TITOOLSROOT=<path to XDC, XDAIS>
29export TIVIDEOTOOLSROOT=<path to CE, FC>
30export IPCHEADERS=<path to IPC Headers>
31export INSTALL_ROOT=<path for copying output binaries>
32export QCONF_OVERRIDE=<absolute path to libdce/nto/qconf-override.mk>
33export IVAHDCODECS=<path to ipumm/extrel/ti/ivahd_codecs>
34
35For IPCHEADERS - Headers should be at:
36$(IPCHEADERS)/usr/include/memmgr
37$(IPCHEADERS)/usr/include/ti/syslink/
38$(IPCHEADERS)/usr/include/ti/ipc/mm
39$(IPCHEADERS)/usr/include/ti/shmemallocator
40$(IPCHEADERS)/usr/include/
41
42Building:
43make install
44
45Clean:
46make clean
47
48Location of Binaries:
49INSTALL_ROOT/armle-v7/usr/lib/libdce.so
50INSTALL_ROOT/armle-v7/usr/lib/libdce.so.1
51INSTALL_ROOT/armle-v7/bin/dce_test
diff --git a/common.mk b/common.mk
new file mode 100644
index 0000000..b430901
--- /dev/null
+++ b/common.mk
@@ -0,0 +1,62 @@
1###################### QNX DCE Build Config #######################
2
3#### Include qconfig.mk
4ifndef QCONFIG
5QCONFIG=qconfig.mk
6endif
7
8include $(QCONFIG)
9
10#### Overriding qrules.mk macros before including qtargets.mk
11
12# Flags to add to the C compiler command line
13CCFLAGS+=-O2 -Dxdc_target_types__=qnx/targets/arm/std.h -DBUILDOS_QNX=1
14
15# To get final library name as "libdce". Needed as project name is not dce
16NAME=dce
17
18### Add files to be included for Build
19TITOOLSROOT ?= /usr/local
20TIVIDEOTOOLSROOT ?= $(TITOOLSROOT)
21# Different tool versions can easily be programmed by defining below variables
22# in your environment.
23CEVERSION ?= codec_engine_3_23_00_07
24FCVERSION ?= framework_components_3_23_03_17
25XDAISVERSION ?= xdais_7_23_00_06
26XDCVERSION ?= xdctools_3_25_00_48
27IPCHEADERS ?= $(INSTALL_ROOT_nto)
28
29# Generate the full package paths for tools
30CEPROD = $(TIVIDEOTOOLSROOT)/$(CEVERSION)
31FCPROD = $(TIVIDEOTOOLSROOT)/$(FCVERSION)
32XDAISPROD = $(TITOOLSROOT)/$(XDAISVERSION)
33XDCPROD = $(TITOOLSROOT)/$(XDCVERSION)
34
35EXTRA_INCVPATH += $(CEPROD)/packages
36EXTRA_INCVPATH += $(FCPROD)/packages
37EXTRA_INCVPATH += $(XDAISPROD)/packages
38EXTRA_INCVPATH += $(XDCPROD)/packages
39EXTRA_INCVPATH += $(IPCHEADERS)/usr/include/memmgr
40EXTRA_INCVPATH += $(IPCHEADERS)/usr/include/ti/syslink/
41EXTRA_INCVPATH += $(IPCHEADERS)/usr/include/ti/ipc/mm
42EXTRA_INCVPATH += $(IPCHEADERS)/usr/include/ti/shmemallocator
43EXTRA_INCVPATH += $(IPCHEADERS)/usr/include/
44
45# Include IPC libraries
46LIBS += memmgr mmrpc sharedmemallocatorS
47
48# Include qmacros.mk
49include $(MKFILES_ROOT)/qmacros.mk
50
51#### Overriding qtargets.mk macros before including qtargets.mk
52INSTALLDIR=usr/lib
53INSTALLDIR+=usr/local
54
55define PINFO
56PINFO DESCRIPTION = libdce codec
57endef
58
59#### Include qtargets.mk, it internally includes qrules.mk
60include $(MKFILES_ROOT)/qtargets.mk
61
62#### Post-set make macros after including qtargets.mk (if-any)
diff --git a/dce_priv.h b/dce_priv.h
new file mode 100644
index 0000000..dea43d4
--- /dev/null
+++ b/dce_priv.h
@@ -0,0 +1,64 @@
1/*
2 * Copyright (c) 2013, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#ifndef __DCE_PRIV_H__
34#define __DCE_PRIV_H__
35
36#include <sys/slog.h>
37
38/********************* MACROS ************************/
39/***************** TRACE MACROS *********************/
40/* Need to make it OS specific and support different trace levels */
41#define ERROR(FMT, ...) do { \
42 slogf(42, _SLOG_INFO, "%s:%d:\t%s\terror: " FMT, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
43} while( 0 )
44#define DEBUG(FMT, ...) do { \
45 slogf(42, _SLOG_DEBUG2, "%s:%d:\t%s\tdebug: " FMT, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
46} while( 0 )
47
48
49/***************** ASSERT MACROS *********************/
50#define _ASSERT_AND_EXECUTE(_COND_, _ERRORCODE_, _EXPR_) do { \
51 if( !(_COND_)) { eError = _ERRORCODE_; \
52 ERROR("Failed %s error val %d", # _COND_, _ERRORCODE_); \
53 _EXPR_; \
54 goto EXIT; } \
55} while( 0 )
56
57#define _ASSERT(_COND_, _ERRORCODE_) do { \
58 if( !(_COND_)) { eError = _ERRORCODE_; \
59 ERROR("Failed %s error val %d", # _COND_, _ERRORCODE_); \
60 goto EXIT; } \
61} while( 0 )
62
63#endif /* __DCE_PRIV_H__ */
64
diff --git a/dce_rpc.h b/dce_rpc.h
new file mode 100644
index 0000000..8082d76
--- /dev/null
+++ b/dce_rpc.h
@@ -0,0 +1,145 @@
1/*
2 * Copyright (c) 2013, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#ifndef __DCE_RPC_H__
34#define __DCE_RPC_H__
35
36/* RPC layer types.. these define the payload of messages between IPUMM
37 * and MPU. This should be kept in sync between firmware build and
38 * driver.
39 *
40 * TODO: xxx_control(XDM_GETVERSION) is a bit awkward to deal with, because
41 * this seems to be the one special case where status->data is used..
42 * possibly we should define a special ioctl and msg to handle this case.
43 */
44
45#define DCE_DEVICE_NAME "rpmsg-dce"
46
47/* Message-Ids:
48 */
49//#define DCE_RPC_CONNECT (0x80000000 | 00) Connect not needed anymore.
50typedef enum dce_rpc_call {
51 DCE_RPC_ENGINE_OPEN = 0,
52 DCE_RPC_ENGINE_CLOSE,
53 DCE_RPC_CODEC_CREATE,
54 DCE_RPC_CODEC_CONTROL,
55 DCE_RPC_CODEC_GET_VERSION,
56 DCE_RPC_CODEC_PROCESS,
57 DCE_RPC_CODEC_DELETE
58} dce_rpc_call;
59
60
61typedef enum dce_codec_type {
62 OMAP_DCE_VIDENC2 = 1,
63 OMAP_DCE_VIDDEC3 = 2
64} dce_codec_type;
65
66/* Structures of RPC */
67typedef struct dce_connect {
68 uint32_t chipset_id;
69 uint32_t debug;
70} dce_connect;
71
72typedef struct dce_engine_open {
73 char name[32]; /* engine name (in) */
74 Engine_Error error_code; /* error code (out) */
75 Engine_Handle eng_handle; /* engine handle (out) */
76} dce_engine_open;
77
78typedef struct dce_engine_close {
79 Engine_Handle eng_handle; /* engine handle (in) */
80} dce_engine_close;
81
82typedef struct dce_codec_create {
83 Engine_Handle engine;
84 char codec_name[32];
85 void *static_params;
86 dce_codec_type codec_id;
87 void *codec_handle;
88} dce_codec_create;
89
90typedef struct dce_codec_control {
91 void *codec_handle;
92 uint32_t cmd_id;
93 void *dyn_params;
94 void *status;
95 dce_codec_type codec_id;
96 int32_t result;
97} dce_codec_control;
98
99typedef struct dce_codec_get_version {
100 void *codec_handle;
101 void *dyn_params;
102 void *status;
103 void *version;
104 dce_codec_type codec_id;
105 int32_t result;
106} dce_codec_get_version;
107
108typedef struct dce_codec_delete {
109 void *codec_handle;
110 dce_codec_type codec_id;
111} dce_codec_delete;
112
113/* ---------------------- For GLP DCE -----------------------------*/
114/* NOTE: CODEC_PROCESS does somewhat more than the other ioctls, in that it
115 * handles buffer mapping/unmapping. So the inBufs/outBufs are copied inline
116 * (with translated addresses in the copy sent inline with codec_process_req).
117 * Since we need the inputID from inArgs, and it is a small struct, it is also
118 * copied inline.
119 *
120 * Therefore, the variable length data[] section has the format:
121 * uint8_t reloc[reloc_length * 4];
122 * uint8_t inargs[in_args_length * 4];
123 * uint8_t outbufs[in_bufs_length * 4];
124 * uint8_t inbufs[in_bufs_length * 4];
125 */
126
127#define MAX_INPUT_BUF 2 // Need to confirm for interlaced YUVs for Encoders
128#define MAX_OUTPUT_BUF 2
129#define MAX_TOTAl_BUF (MAX_INPUT_BUF + MAX_OUTPUT_BUF)
130
131/* Struct to be used if approach [3] of Mmrpc call is followed */
132typedef struct dce_codec_process {
133 void *codec_handle;
134 void *inBufs;
135 void *outBufs;
136 void *inArgs;
137 void *outArgs;
138 int32_t input_Buf[MAX_INPUT_BUF];
139 int32_t output_Buf[MAX_OUTPUT_BUF];
140 dce_codec_type codec_id;
141 int32_t result;
142} dce_codec_process;
143
144#endif /* __DCE_RPC_H__ */
145
diff --git a/libdce.c b/libdce.c
new file mode 100644
index 0000000..bffebac
--- /dev/null
+++ b/libdce.c
@@ -0,0 +1,711 @@
1/*
2 * Copyright (c) 2013, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/*
34********************************** Notes ******************************************
35*******
36********************************* Memory *****************************************
37*
38*******
39********************************* IPC 3.x *****************************************
40* Two approaches are followed for IPC MmRpc calls.
41* 1. All the parameters which need to be sent and received to/from IPU are coupled in a struct
42* allocated from Shared Memory. Only the adrress of the struct is passed to MmRpc
43* as a pointer argument. This approach is useful as MmRpc in some cases to avoid multiple
44* translations.
45* This approach is followed for :
46* Engine_open(), Engine_close(), create(), control(), delete()
47* For understanding refer to the Mmrpc_test.c in IPC 3.x
48* 2. All the parameters which need to be sent are given as separate arguments to
49* MmRpc. This appraoch is needed when you need to translate an address which is
50* ofsetted from a pointer which in itself needs to be translated.
51* This apporach is followed for : process()
52* For understanding, take the example of inbufs argument in process call(). Inbufs
53* allocated in Shared memory and needs to be translated, has the address of Input
54* buffer (allocated from Tiler). It is not possible to give the Input buffer as an argument
55* to Mmrpc for translation until inbufs is given as a parameter to Mmrpc. Therefore inbuf
56* can't be populated inside another Shared memory struct.
57* 3. This approach is a workaround to use approach [1] by solving the issue posed by [2].
58* This approach is followed for : get_version()
59* Taking the example of inbufs to explain, the Input buffer address will be one of the
60* parameters of the struct (explained in [1]) along with inbufs address. Therefore the
61* Input buffer address will get translated here. At the IPU, this address needs to be
62* copied back to inbufs.
63*********************************************************************************
64*/
65
66#include <stdlib.h>
67#include <string.h>
68#include <stdio.h>
69#include <pthread.h>
70#include <errno.h>
71
72#include <xdc/std.h>
73
74#if defined(BUILDOS_GLP)
75#include <xf86drm.h>
76#include <omap_drm.h>
77#include <omap_dce.h>
78#include <omap_drmif.h>
79#endif /* BUILDOS_GLP */
80
81/* IPC Headers */
82#include <MmRpc.h>
83
84/*DCE Headers */
85#include "libdce.h"
86#include "dce_rpc.h"
87#include "dce_priv.h"
88#include "memplugin.h"
89
90
91#if defined(BUILDOS_GLP)
92#ifdef GLP_X11
93int dce_auth_x11(int *fd);
94#endif /* GLP_X11 */
95#ifdef GLP_WAYLAND
96int dce_auth_wayland(int *fd);
97#endif /* GLP_WAYLAND */
98
99static int fd = -1;
100static struct omap_device *dev;
101static int ioctl_base;
102#define CMD(name) (ioctl_base + DRM_OMAP_DCE_##name)
103
104uint32_t dce_debug = 3;
105#endif /* BUILDOS_GLP */
106
107
108/********************* GLOBALS ***********************/
109/* Hande used for Remote Communication */
110static MmRpc_Handle MmRpcHandle = NULL;
111static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
112static int count = 0;
113
114
115/****************** INLINE FUNCTIONS ********************/
116
117static inline void Fill_MmRpc_fxnCtx(MmRpc_FxnCtx *fxnCtx, int fxn_id, int num_params, int num_xlts, MmRpc_Xlt *xltAry)
118{
119 fxnCtx->fxn_id = fxn_id;
120 fxnCtx->num_params = num_params;
121 fxnCtx->num_xlts = num_xlts;
122 fxnCtx->xltAry = xltAry;
123}
124
125static inline void Fill_MmRpc_fxnCtx_Ptr_Params(MmRpc_Param *mmrpc_params, int size, void *addr, void *handle)
126{
127 mmrpc_params->type = MmRpc_ParamType_Ptr;
128 mmrpc_params->param.ptr.size = size;
129 mmrpc_params->param.ptr.addr = (size_t)addr;
130 mmrpc_params->param.ptr.handle = (size_t)handle;
131}
132
133static inline void Fill_MmRpc_fxnCtx_Scalar_Params(MmRpc_Param *mmrpc_params, int size, int data)
134{
135 mmrpc_params->type = MmRpc_ParamType_Scalar;
136 mmrpc_params->param.scalar.size = size;
137 mmrpc_params->param.scalar.data = (size_t)data;
138}
139
140static inline void Fill_MmRpc_fxnCtx_Xlt_Array(MmRpc_Xlt *mmrpc_xlt, int index, int32_t base, int32_t addr, void *handle)
141{
142 /* index : index of params filled in FxnCtx */
143 /* base : user Virtual Address as per definition in MmRpc and not base from where offset is calculated */
144 /* offset : calculated from address of index */
145 mmrpc_xlt->index = index;
146 mmrpc_xlt->offset = MmRpc_OFFSET(base, addr);
147 mmrpc_xlt->base = (size_t)addr;
148 mmrpc_xlt->handle = (size_t)handle;
149}
150
151/************************ FUNCTIONS **************************/
152/* Interface for QNX for parameter buffer allocation */
153/* These interfaces are implemented to maintain Backward Compatability */
154void *dce_alloc(int sz)
155{
156 return (memplugin_alloc(sz, 0, TILER_1D_BUFFER));
157}
158
159void dce_free(void *ptr)
160{
161 memplugin_free(ptr, TILER_1D_BUFFER);
162}
163
164/*************** Startup/Shutdown Functions ***********************/
165static int dce_init(void)
166{
167 dce_error_status eError = DCE_EOK;
168 MmRpc_Params args;
169
170 printf(" >> dce_init\n");
171
172 pthread_mutex_lock(&mutex);
173
174 count++;
175 /* Check if already Initialized */
176 _ASSERT(count == 1, DCE_EOK);
177
178 /* Create remote server insance */
179 MmRpc_Params_init(&args);
180
181 eError = MmRpc_create(DCE_DEVICE_NAME, &args, &MmRpcHandle);
182
183 _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CREATE_FAIL, count--);
184
185 printf("open(/dev/" DCE_DEVICE_NAME ") -> 0x%x\n", (int)MmRpcHandle);
186EXIT:
187 pthread_mutex_unlock(&mutex);
188 return (eError);
189}
190
191static void dce_deinit(void)
192{
193 pthread_mutex_lock(&mutex);
194
195 count--;
196 if( count > 0 ) {
197 goto EXIT;
198 }
199
200 if( MmRpcHandle != NULL ) {
201 MmRpc_delete(&MmRpcHandle);
202 }
203 MmRpcHandle = NULL;
204EXIT:
205 pthread_mutex_unlock(&mutex);
206 return;
207}
208
209/*===============================================================*/
210/** Engine_open : Open Codec Engine.
211 *
212 * @ param attrs [in] : Engine Attributes. This param is not passed to Remote core.
213 * @ param name [in] : Name of Encoder or Decoder codec.
214 * @ param ec [out] : Error returned by Codec Engine.
215 * @ return : Codec Engine Handle is returned to be used to create codec.
216 * In case of error, NULL is returned as Engine Handle.
217 */
218Engine_Handle Engine_open(String name, Engine_Attrs *attrs, Engine_Error *ec)
219{
220 MmRpc_FxnCtx fxnCtx;
221 int32_t fxnRet;
222 dce_error_status eError = DCE_EOK;
223 dce_engine_open *engine_open_msg = NULL;
224 Engine_Handle eng_handle = NULL;
225
226 _ASSERT(name != '\0', DCE_EINVALID_INPUT);
227 _ASSERT(ec != NULL, DCE_EINVALID_INPUT);
228
229 /* Initialize DCE and IPC. In case of Error Deinitialize them */
230 _ASSERT_AND_EXECUTE(dce_init() == DCE_EOK, DCE_EIPC_CREATE_FAIL, dce_deinit());
231
232 printf(">> Engine_open Params::name = %s size = %d\n", name, strlen(name));
233 /* Allocate Shared memory for the engine_open rpc msg structure*/
234 /* Tiler Memory preferred for now for First level testing */
235 engine_open_msg = memplugin_alloc(sizeof(dce_engine_open), 0, TILER_1D_BUFFER);
236
237 _ASSERT_AND_EXECUTE(engine_open_msg != NULL, DCE_EOUT_OF_MEMORY, eng_handle = NULL);
238
239 /* Populating the msg structure with all the params */
240 /* Populating all params into a struct avoid individual address translations of name, ec */
241 strncpy(engine_open_msg->name, name, strlen(name));
242 engine_open_msg->eng_handle = NULL;
243
244 /* Marshall function arguments into the send buffer */
245 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_ENGINE_OPEN, 1, 0, NULL);
246 Fill_MmRpc_fxnCtx_Ptr_Params(fxnCtx.params, sizeof(dce_engine_open), engine_open_msg, NULL);
247
248 /* Invoke the Remote function through MmRpc */
249 eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
250
251 /* In case of Error, the Application will get a NULL Engine Handle */
252 _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CALL_FAIL, eng_handle = NULL);
253
254 /* Populate return arguments */
255 eng_handle = engine_open_msg->eng_handle;
256 ec[0] = engine_open_msg->error_code;
257
258EXIT:
259 memplugin_free(engine_open_msg, TILER_1D_BUFFER);
260
261 return (eng_handle);
262}
263
264/*===============================================================*/
265/** Engine_close : Close Engine.
266 *
267 * @ param engine [in] : Engine Handle obtained in Engine_open() call.
268 */
269Void Engine_close(Engine_Handle engine)
270{
271 MmRpc_FxnCtx fxnCtx;
272 int32_t fxnRet;
273 dce_error_status eError = DCE_EOK;
274 dce_engine_close *engine_close_msg = NULL;
275
276 _ASSERT(engine != NULL, DCE_EINVALID_INPUT);
277
278 /* Allocate Shared/Tiler memory for the engine_close rpc msg structure*/
279 engine_close_msg = memplugin_alloc(sizeof(dce_engine_close), 0, TILER_1D_BUFFER);
280
281 _ASSERT(engine_close_msg != NULL, DCE_EOUT_OF_MEMORY);
282
283 /* Populating the msg structure with all the params */
284 engine_close_msg->eng_handle = engine;
285
286 /* Marshall function arguments into the send buffer */
287 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_ENGINE_CLOSE, 1, 0, NULL);
288 Fill_MmRpc_fxnCtx_Ptr_Params(fxnCtx.params, sizeof(dce_engine_close), engine_close_msg, NULL);
289
290 /* Invoke the Remote function through MmRpc */
291 eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
292
293 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
294
295EXIT:
296 memplugin_free(engine_close_msg, TILER_1D_BUFFER);
297
298 dce_deinit();
299 return;
300}
301
302/*===============================================================*/
303/** Functions create(), control(), get_version(), process(), delete() are common codec
304 * glue function signatures which are same for both encoder and decoder
305 */
306/*===============================================================*/
307/** create : Create Encoder/Decoder codec.
308 *
309 * @ param engine [in] : Engine Handle obtained in Engine_open() call.
310 * @ param name [in] : Name of Encoder or Decoder codec.
311 * @ param params [in] : Static parameters of codec.
312 * @ param codec_id [in] : To differentiate between Encoder and Decoder codecs.
313 * @ return : Codec Handle is returned to be used for control, process, delete calls.
314 * In case of error, NULL is returned.
315 */
316static void *create(Engine_Handle engine, String name, void *params, dce_codec_type codec_id)
317{
318 MmRpc_FxnCtx fxnCtx;
319 MmRpc_Xlt xltAry;
320 int32_t fxnRet;
321 dce_error_status eError = DCE_EOK;
322 dce_codec_create *codec_create_msg = NULL;
323 void *codec_handle = NULL;
324
325 _ASSERT(name != '\0', DCE_EINVALID_INPUT);
326 _ASSERT(engine != NULL, DCE_EINVALID_INPUT);
327 _ASSERT(params != NULL, DCE_EINVALID_INPUT);
328
329 /* Allocate Shared/Tiler memory for the codec_create rpc msg structure*/
330 codec_create_msg = memplugin_alloc(sizeof(dce_codec_create), 0, TILER_1D_BUFFER);
331
332 _ASSERT_AND_EXECUTE(codec_create_msg != NULL, DCE_EOUT_OF_MEMORY, codec_handle = NULL);
333
334 /* Populating the msg structure with all the params */
335 codec_create_msg->engine = engine;
336 strncpy(codec_create_msg->codec_name, name, strlen(name));
337 codec_create_msg->codec_id = codec_id;
338 codec_create_msg->codec_handle = NULL;
339 codec_create_msg->static_params = params;
340
341 /* Marshall function arguments into the send buffer */
342 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_CREATE, 1, 1, &xltAry);
343 Fill_MmRpc_fxnCtx_Ptr_Params(&(fxnCtx.params[0]), sizeof(dce_codec_create), codec_create_msg, NULL);
344
345 /* Mention the virtual pointers that need translation */
346 /* Allocations through dce_alloc need translation */
347 /* In this case the static params buffer need translation */
348 Fill_MmRpc_fxnCtx_Xlt_Array(fxnCtx.xltAry, 0, (int32_t)codec_create_msg, (int32_t)&(codec_create_msg->static_params), NULL);
349
350 /* Invoke the Remote function through MmRpc */
351 eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
352
353 /* In case of Error, the Application will get a NULL Codec Handle */
354 _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CALL_FAIL, codec_handle = NULL);
355
356 codec_handle = codec_create_msg->codec_handle;
357
358EXIT:
359 memplugin_free(codec_create_msg, TILER_1D_BUFFER);
360
361 return (codec_handle);
362}
363
364/*===============================================================*/
365/** control : Codec control call.
366 *
367 * @ param codec [in] : Codec Handle obtained in create() call.
368 * @ param id [in] : Command id for XDM control operation.
369 * @ param dynParams [in] : Dynamic input parameters to Codec.
370 * @ param status [out] : Codec returned status parameters.
371 * @ param codec_id [in] : To differentiate between Encoder and Decoder codecs.
372 * @ return : Status of control() call is returned.
373 * #XDM_EOK [0] : Success.
374 * #XDM_EFAIL [-1] : Failure.
375 * #IPC_FAIL [-2] : MmRpc Call failed.
376 * #XDM_EUNSUPPORTED [-3] : Unsupported request.
377 * #OUT_OF_MEMORY [-4] : Out of Shared Memory.
378 */
379static XDAS_Int32 control(void *codec, int id, void *dynParams, void *status, dce_codec_type codec_id)
380{
381 MmRpc_FxnCtx fxnCtx;
382 MmRpc_Xlt xltAry[2];
383 int32_t fxnRet;
384 dce_error_status eError = DCE_EOK;
385 dce_codec_control *codec_control_msg = NULL;
386
387 _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
388 _ASSERT(dynParams != NULL, DCE_EINVALID_INPUT);
389 _ASSERT(status != NULL, DCE_EINVALID_INPUT);
390
391 /* Allocate Shared/Tiler memory for the codec_control rpc msg structure*/
392 codec_control_msg = memplugin_alloc(sizeof(dce_codec_control), 0, TILER_1D_BUFFER);
393
394 _ASSERT(codec_control_msg != NULL, DCE_EOUT_OF_MEMORY);
395
396 /* Populating the msg structure with all the params */
397 codec_control_msg->codec_handle = codec;
398 codec_control_msg->cmd_id = id;
399 codec_control_msg->codec_id = codec_id;
400 codec_control_msg->dyn_params = dynParams;
401 codec_control_msg->status = status;
402
403 /* Marshall function arguments into the send buffer */
404 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_CONTROL, 1, 2, xltAry);
405 Fill_MmRpc_fxnCtx_Ptr_Params(fxnCtx.params, sizeof(dce_codec_control), codec_control_msg, NULL);
406
407 /* Dynamic and status params buffer need translation */
408 Fill_MmRpc_fxnCtx_Xlt_Array(fxnCtx.xltAry, 0, (int32_t)codec_control_msg, (int32_t)&(codec_control_msg->dyn_params), NULL);
409 Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[1]), 0, (int32_t)codec_control_msg, (int32_t)&(codec_control_msg->status), NULL);
410
411 /* Invoke the Remote function through MmRpc */
412 eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
413
414 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
415
416 eError = codec_control_msg->result;
417
418EXIT:
419 memplugin_free(codec_control_msg, TILER_1D_BUFFER);
420
421 return (eError);
422}
423
424/*===============================================================*/
425/** get_version : Codec control call to get the codec version. This call has been made
426 * separate from control call because it involves an additional version
427 * buffer translation.
428 *
429 * @ param codec [in] : Codec Handle obtained in create() call.
430 * @ param id [in] : Command id for XDM control operation.
431 * @ param dynParams [in] : Dynamic input parameters to Codec.
432 * @ param status [out] : Codec returned status parameters.
433 * @ param codec_id [in] : To differentiate between Encoder and Decoder codecs.
434 * @ return : Status of control() call is returned.
435 * #XDM_EOK [0] : Success.
436 * #XDM_EFAIL [-1] : Failure.
437 * #IPC_FAIL [-2] : MmRpc Call failed.
438 * #XDM_EUNSUPPORTED [-3] : Unsupported request.
439 * #OUT_OF_MEMORY [-4] : Out of Shared Memory.
440 */
441static XDAS_Int32 get_version(void *codec, void *dynParams, void *status, dce_codec_type codec_id)
442{
443 MmRpc_FxnCtx fxnCtx;
444 MmRpc_Xlt xltAry[3];
445 int32_t fxnRet;
446 dce_error_status eError = DCE_EOK;
447 dce_codec_get_version *codec_get_version_msg = NULL;
448
449 _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
450 _ASSERT(dynParams != NULL, DCE_EINVALID_INPUT);
451 _ASSERT(status != NULL, DCE_EINVALID_INPUT);
452
453 /* Allocate Shared/Tiler memory for the codec_get_version rpc msg structure*/
454 codec_get_version_msg = memplugin_alloc(sizeof(dce_codec_get_version), 0, TILER_1D_BUFFER);
455
456 _ASSERT(codec_get_version_msg != NULL, DCE_EOUT_OF_MEMORY);
457
458 /* Populating the msg structure with all the params */
459 codec_get_version_msg->codec_handle = codec;
460 codec_get_version_msg->codec_id = codec_id;
461 codec_get_version_msg->dyn_params = dynParams;
462 codec_get_version_msg->status = status;
463 if( codec_id == OMAP_DCE_VIDDEC3 ) {
464 codec_get_version_msg->version = ((IVIDDEC3_Status *)status)->data.buf;
465 } else if( codec_id == OMAP_DCE_VIDENC2 ) {
466 codec_get_version_msg->version = ((IVIDDEC3_Status *)status)->data.buf;
467 }
468
469 /* Marshall function arguments into the send buffer */
470 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_CONTROL, 1, 3, xltAry);
471 Fill_MmRpc_fxnCtx_Ptr_Params(fxnCtx.params, sizeof(dce_codec_get_version), codec_get_version_msg, NULL);
472
473 /* Dynamic, status params and version info buffer need translation */
474 Fill_MmRpc_fxnCtx_Xlt_Array(fxnCtx.xltAry, 0, (int32_t)codec_get_version_msg, (int32_t)&(codec_get_version_msg->dyn_params), NULL);
475 Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[1]), 0, (int32_t)codec_get_version_msg, (int32_t)&(codec_get_version_msg->status), NULL);
476 Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[2]), 0, (int32_t)codec_get_version_msg, (int32_t)&(codec_get_version_msg->version), NULL);
477
478 /* Invoke the Remote function through MmRpc */
479 eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
480
481 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
482
483 eError = codec_get_version_msg->result;
484
485EXIT:
486 memplugin_free(codec_get_version_msg, TILER_1D_BUFFER);
487
488 return (eError);
489}
490
491typedef enum process_call_params {
492 CODEC_HANDLE_INDEX = 0,
493 INBUFS_INDEX,
494 OUTBUFS_INDEX,
495 INARGS_INDEX,
496 OUTARGS_INDEX,
497 CODEC_ID_INDEX
498} process_call_params;
499
500/*===============================================================*/
501/** process : Encode/Decode process.
502 *
503 * @ param codec [in] : Codec Handle obtained in create() call.
504 * @ param inBufs [in] : Input buffer details.
505 * @ param outBufs [in] : Output buffer details.
506 * @ param inArgs [in] : Input arguments.
507 * @ param outArgs [out] : Output arguments.
508 * @ param codec_id [in] : To differentiate between Encoder and Decoder codecs.
509 * @ return : Status of the process call.
510 * #XDM_EOK [0] : Success.
511 * #XDM_EFAIL [-1] : Failure.
512 * #IPC_FAIL [-2] : MmRpc Call failed.
513 * #XDM_EUNSUPPORTED [-3] : Unsupported request.
514 */
515static XDAS_Int32 process(void *codec, void *inBufs, void *outBufs,
516 void *inArgs, void *outArgs, dce_codec_type codec_id)
517{
518 MmRpc_FxnCtx fxnCtx;
519 MmRpc_Xlt xltAry[MAX_TOTAl_BUF];
520 int fxnRet, count, total_count, numInBufs = 0, numOutBufs = 0, sz[5] = { 0 };
521 dce_error_status eError = DCE_EOK;
522
523 _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
524 _ASSERT(inBufs != NULL, DCE_EINVALID_INPUT);
525 _ASSERT(outBufs != NULL, DCE_EINVALID_INPUT);
526 _ASSERT(inArgs != NULL, DCE_EINVALID_INPUT);
527 _ASSERT(outArgs != NULL, DCE_EINVALID_INPUT);
528
529 if( codec_id == OMAP_DCE_VIDDEC3 ) {
530 numInBufs = ((XDM2_BufDesc *)inBufs)->numBufs;
531 numOutBufs = ((XDM2_BufDesc *)outBufs)->numBufs;
532 sz[INBUFS_INDEX] = sizeof(XDM2_BufDesc);
533 sz[OUTBUFS_INDEX] = sizeof(XDM2_BufDesc);
534 sz[INARGS_INDEX] = sizeof(VIDDEC3_InArgs);
535 sz[OUTARGS_INDEX] = sizeof(VIDDEC3_OutArgs);
536 } else if( codec_id == OMAP_DCE_VIDENC2 ) {
537 numInBufs = ((IVIDEO2_BufDesc *)inBufs)->numPlanes;
538 numOutBufs = ((XDM2_BufDesc *)outBufs)->numBufs;
539 sz[INBUFS_INDEX] = sizeof(IVIDEO2_BufDesc);
540 sz[OUTBUFS_INDEX] = sizeof(XDM2_BufDesc);
541 sz[INARGS_INDEX] = sizeof(VIDENC2_InArgs);
542 sz[OUTARGS_INDEX] = sizeof(VIDENC2_OutArgs);
543 }
544
545 /* marshall function arguments into the send buffer */
546 /* Approach [2] as explained in "Notes" used for process */
547 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_PROCESS, 6, numInBufs + numOutBufs, xltAry);
548 Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[CODEC_HANDLE_INDEX]), sizeof(int32_t), (int32_t)codec);
549 Fill_MmRpc_fxnCtx_Ptr_Params(&(fxnCtx.params[INBUFS_INDEX]), sz[INBUFS_INDEX], inBufs, NULL);
550 Fill_MmRpc_fxnCtx_Ptr_Params(&(fxnCtx.params[OUTBUFS_INDEX]), sz[OUTBUFS_INDEX], outBufs, NULL);
551 Fill_MmRpc_fxnCtx_Ptr_Params(&(fxnCtx.params[INARGS_INDEX]), sz[INARGS_INDEX], inArgs, NULL);
552 Fill_MmRpc_fxnCtx_Ptr_Params(&(fxnCtx.params[OUTARGS_INDEX]), sz[OUTARGS_INDEX], outArgs, NULL);
553 Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[CODEC_ID_INDEX]), sizeof(int32_t), codec_id);
554
555 /* InBufs, OutBufs, InArgs, OutArgs buffer need translation but since they have been */
556 /* individually mentioned as fxnCtx Params, they need not be mentioned below again */
557 /* Input and Output Buffers have to be mentioned for translation */
558 for( count = 0, total_count = 0; count < numInBufs; count++, total_count++ ) {
559 if( codec_id == OMAP_DCE_VIDDEC3 ) {
560 Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), INBUFS_INDEX, (int32_t)inBufs, (int32_t)&(((XDM2_BufDesc *)inBufs)->descs[count].buf), NULL);
561 } else if( codec_id == OMAP_DCE_VIDENC2 ) {
562 Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), INBUFS_INDEX, (int32_t)inBufs, (int32_t)&(((IVIDEO2_BufDesc *)inBufs)->planeDesc[count].buf), NULL);
563 }
564 }
565
566 for( count = 0; count < numOutBufs; count++, total_count++ ) {
567 Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), OUTBUFS_INDEX, (int32_t)outBufs, (int32_t)&(((XDM2_BufDesc *)outBufs)->descs[count].buf), NULL);
568 }
569
570 /* Invoke the Remote function through MmRpc */
571 eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
572
573 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
574
575 eError = (dce_error_status)(fxnRet);
576EXIT:
577 return (eError);
578}
579
580/*===============================================================*/
581/** delete : Delete Encode/Decode codec instance.
582 *
583 * @ param codec [in] : Codec Handle obtained in create() call.
584 * @ param codec_id [in] : To differentiate between Encoder and Decoder codecs.
585 * @ return : NIL.
586 */
587static void delete(void *codec, dce_codec_type codec_id)
588{
589 MmRpc_FxnCtx fxnCtx;
590 int32_t fxnRet;
591 dce_error_status eError = DCE_EOK;
592 dce_codec_delete *codec_delete_msg = NULL;
593
594 _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
595
596 /* Allocate Shared/Tiler memory for the codec_delete rpc msg structure*/
597 codec_delete_msg = memplugin_alloc(sizeof(dce_codec_delete), 0, TILER_1D_BUFFER);
598
599 _ASSERT(codec_delete_msg != NULL, DCE_EOUT_OF_MEMORY);
600
601 /* Populating the msg structure with all the params */
602 codec_delete_msg->codec_handle = codec;
603 codec_delete_msg->codec_id = codec_id;
604
605 /* Marshall function arguments into the send buffer */
606 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_DELETE, 1, 0, NULL);
607 Fill_MmRpc_fxnCtx_Ptr_Params(fxnCtx.params, sizeof(dce_codec_delete), codec_delete_msg, NULL);
608
609 /* Invoke the Remote function through MmRpc */
610 eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
611
612 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
613
614EXIT:
615 memplugin_free(codec_delete_msg, TILER_1D_BUFFER);
616
617 return;
618}
619
620/*************** Deocder Codec Engine Functions ***********************/
621VIDDEC3_Handle VIDDEC3_create(Engine_Handle engine, String name,
622 VIDDEC3_Params *params)
623{
624 VIDDEC3_Handle codec;
625
626 DEBUG(">> engine=%p, name=%s, params=%p", engine, name, params);
627 codec = create(engine, name, params, OMAP_DCE_VIDDEC3);
628 DEBUG("<< codec=%p", codec);
629 return (codec);
630}
631
632XDAS_Int32 VIDDEC3_control(VIDDEC3_Handle codec, VIDDEC3_Cmd id,
633 VIDDEC3_DynamicParams *dynParams, VIDDEC3_Status *status)
634{
635 XDAS_Int32 ret;
636
637 DEBUG(">> codec=%p, id=%d, dynParams=%p, status=%p",
638 codec, id, dynParams, status);
639 if( id == XDM_GETVERSION ) {
640 ret = get_version(codec, dynParams, status, OMAP_DCE_VIDDEC3);
641 } else {
642 ret = control(codec, id, dynParams, status, OMAP_DCE_VIDDEC3);
643 }
644 DEBUG("<< ret=%d", ret);
645 return (ret);
646}
647
648XDAS_Int32 VIDDEC3_process(VIDDEC3_Handle codec,
649 XDM2_BufDesc *inBufs, XDM2_BufDesc *outBufs,
650 VIDDEC3_InArgs *inArgs, VIDDEC3_OutArgs *outArgs)
651{
652 XDAS_Int32 ret;
653
654 DEBUG(">> codec=%p, inBufs=%p, outBufs=%p, inArgs=%p, outArgs=%p",
655 codec, inBufs, outBufs, inArgs, outArgs);
656 ret = process(codec, inBufs, outBufs, inArgs, outArgs, OMAP_DCE_VIDDEC3);
657 DEBUG("<< ret=%d", ret);
658 return (ret);
659}
660
661Void VIDDEC3_delete(VIDDEC3_Handle codec)
662{
663 DEBUG(">> codec=%p", codec);
664 delete(codec, OMAP_DCE_VIDDEC3);
665 DEBUG("<<");
666}
667
668/*************** Enocder Codec Engine Functions ***********************/
669VIDENC2_Handle VIDENC2_create(Engine_Handle engine, String name,
670 VIDENC2_Params *params)
671{
672 VIDENC2_Handle codec;
673
674 DEBUG(">> engine=%p, name=%s, params=%p", engine, name, params);
675 codec = create(engine, name, params, OMAP_DCE_VIDENC2);
676 DEBUG("<< codec=%p", codec);
677 return (codec);
678}
679
680XDAS_Int32 VIDENC2_control(VIDENC2_Handle codec, VIDENC2_Cmd id,
681 VIDENC2_DynamicParams *dynParams, VIDENC2_Status *status)
682{
683 XDAS_Int32 ret;
684
685 DEBUG(">> codec=%p, id=%d, dynParams=%p, status=%p",
686 codec, id, dynParams, status);
687 ret = control(codec, id, dynParams, status, OMAP_DCE_VIDENC2);
688 DEBUG("<< ret=%d", ret);
689 return (ret);
690}
691
692XDAS_Int32 VIDENC2_process(VIDENC2_Handle codec,
693 IVIDEO2_BufDesc *inBufs, XDM2_BufDesc *outBufs,
694 VIDENC2_InArgs *inArgs, VIDENC2_OutArgs *outArgs)
695{
696 XDAS_Int32 ret;
697
698 DEBUG(">> codec=%p, inBufs=%p, outBufs=%p, inArgs=%p, outArgs=%p",
699 codec, inBufs, outBufs, inArgs, outArgs);
700 ret = process(codec, inBufs, outBufs, inArgs, outArgs, OMAP_DCE_VIDENC2);
701 DEBUG("<< ret=%d", ret);
702 return (ret);
703}
704
705Void VIDENC2_delete(VIDENC2_Handle codec)
706{
707 DEBUG(">> codec=%p", codec);
708 delete(codec, OMAP_DCE_VIDENC2);
709 DEBUG("<<");
710}
711
diff --git a/libdce.h b/libdce.h
new file mode 100644
index 0000000..c64456a
--- /dev/null
+++ b/libdce.h
@@ -0,0 +1,79 @@
1/*
2 * Copyright (c) 2013, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#ifndef __LIBDCE_H__
34#define __LIBDCE_H__
35
36
37#include <ti/sdo/ce/Engine.h>
38#include <ti/sdo/ce/video3/viddec3.h>
39#include <ti/sdo/ce/video2/videnc2.h>
40
41
42/* DCE Error Types */
43typedef enum dce_error_status {
44 DCE_EOK = 0,
45 DCE_EXDM_FAIL = -1,
46 DCE_EOUT_OF_MEMORY = -2,
47 DCE_EXDM_UNSUPPORTED = -3,
48 DCE_EIPC_CREATE_FAIL = -4,
49 DCE_EIPC_CALL_FAIL = -5,
50 DCE_EINVALID_INPUT = -6
51} dce_error_status;
52
53
54/* other than the codec-engine API, you must use the following two functions
55 * to allocate the data structures passed to codec-engine APIs (other than the
56 * raw input/output buffers which should be passed as virtual addresses in
57 * TILER space
58 */
59void *dce_alloc(int sz);
60void dce_free(void *ptr);
61
62
63#if defined(BUILDOS_GLP)
64void dce_set_fd(int fd);
65int dce_get_fd();
66
67/* avoid some messy stuff in xdc/std.h which leads to gcc issues */
68#define xdc__ARGTOPTR
69#define xdc__ARGTOFXN
70
71struct omap_device *dce_init(void);
72void dce_deinit(struct omap_device *dev);
73
74#define XDM_MEMTYPE_BO 10
75#define XDM_MEMTYPE_BO_OFFSET 11
76#endif /* BUILDOS_GLP */
77
78#endif /* __LIBDCE_H__ */
79
diff --git a/memplugin.h b/memplugin.h
new file mode 100644
index 0000000..f4dda8e
--- /dev/null
+++ b/memplugin.h
@@ -0,0 +1,81 @@
1/*
2 * Copyright (c) 2013, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#ifndef __MEMPLUGIN_H__
34#define __MEMPLUGIN_H__
35
36#include <stdlib.h>
37#include <string.h>
38#include <stdio.h>
39
40#if defined(BUILDOS_QNX)
41#include <memmgr.h>
42#endif /* BUILDOS_QNX */
43
44#if defined(BUILDOS_GLP)
45#include <xf86drm.h>
46#endif /* BUILDOS_GLP */
47
48/* IPC Headers */
49#include <tilermem.h>
50#include <SharedMemoryAllocatorUsr.h>
51
52
53#define P2H(p) (&(((MemHeader *)(p))[-1]))
54#define H2P(h) ((void *)&(h)[1])
55
56typedef enum mem_type {
57 TILER_1D_BUFFER,
58 TILER8_2D_BUFFER,
59 TILER16_2D_BUFFER,
60 SHARED_MEMORY_BUFFER,
61 MEM_MAX
62} mem_type;
63
64
65/* DCE Error Types */
66typedef enum mem_error_status {
67 MEM_EOK = 0,
68 MEM_EINVALID_INPUT = -1,
69 MEM_EOUT_OF_TILER_MEMORY = -2,
70 MEM_EOUT_OF_SHMEMORY = -3,
71 MEM_EOUT_OF_SYSTEM_MEMORY = -4
72} mem_error_status;
73
74void *memplugin_alloc(int sz, int height, mem_type memory_type);
75
76void memplugin_free(void *ptr, mem_type memory_type);
77
78void *memplugin_share(void *ptr, mem_type memory_type);
79
80#endif /* __MEMPLUGIN_H__ */
81
diff --git a/memplugin_qnx.c b/memplugin_qnx.c
new file mode 100644
index 0000000..5555037
--- /dev/null
+++ b/memplugin_qnx.c
@@ -0,0 +1,158 @@
1/*
2 * Copyright (c) 2013, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "memplugin.h"
34#include "dce_priv.h"
35
36
37/* Would it be good to have MemHeaders for Tiler 2D buffers?? */
38/* Since the decision is to not support allocation of IO buffers, no */
39/* need to worry about Tiler 2D Buffers. Hence below Memheader */
40/* can be used. */
41/*
42typedef struct {
43 dce_memory_type memory_type;
44 union {
45 struct {
46 Uint32 size;
47 Uint32 ducati_addr;
48 } tilerHeader;
49 shm_buf shm_bufHeader;
50 }
51} MemHeader;
52else for Tiler 1D buffers */
53
54/* MemHeader is important because it is necessary to know the */
55/* size of the parameter buffers on IPU for Cache operations */
56/* The size can't be assumed as codec supports different inputs */
57/* For ex: static params can be VIDDEC3_Params, IVIDDEC3_Params */
58/* or IH264DEC_Params */
59typedef struct MemHeader {
60 int size;
61 void *ptr;
62} MemHeader;
63
64
65/* For TILER 2D Buffers : sz = width */
66/* : height = nonzero */
67/* For other memory_types : height = 0 */
68void *memplugin_alloc(int sz, int height, mem_type memory_type)
69{
70 MemHeader *h;
71 shm_buf *handle;
72 MemAllocBlock block;
73 int num_block;
74 mem_error_status eError = MEM_EOK;
75
76 _ASSERT(sz != 0, MEM_EINVALID_INPUT);
77 _ASSERT((memory_type < MEM_MAX) && (memory_type >= TILER_1D_BUFFER), MEM_EINVALID_INPUT);
78
79 /* Tiler buffer Allocations : Only Tiler 1D used for Parameter Buffers and RPC Message buffers */
80 if( memory_type == TILER_1D_BUFFER || memory_type == TILER8_2D_BUFFER || memory_type == TILER16_2D_BUFFER ) {
81 num_block = 1;
82
83 if( memory_type == TILER_1D_BUFFER ) {
84 /* Allocate in tiler paged mode (1d) container */
85 block.pixelFormat = PIXEL_FMT_PAGE;
86 block.dim.len = sz + sizeof(MemHeader);
87#if 0 /* Data Tiler Buffers not to be allocated by DCE */
88 } else if( memory_type == TILER8_2D_BUFFER ) {
89 /* Allocate in tiler 8 bit mode (2d) container */
90 _ASSERT(height != 0, MEM_EINVALID_INPUT);
91 block.pixelFormat = PIXEL_FMT_8BIT;
92 block.dim.area.width = sz;
93 block.dim.area.height = height;
94 } else {
95 /* Allocate in tiler 16 bit mode (2d) container */
96 _ASSERT(height != 0, MEM_EINVALID_INPUT);
97 block.pixelFormat = PIXEL_FMT_16BIT;
98 block.dim.area.width = sz;
99 block.dim.area.height = height;
100#endif
101 }
102 block.stride = 0;
103
104 h = MemMgr_Alloc(&block, num_block);
105
106 _ASSERT(h != NULL, MEM_EOUT_OF_TILER_MEMORY);
107
108 h->size = sz;
109 memset(H2P(h), 0, sz);
110 return (H2P(h));
111 } else {
112
113 handle = malloc(sizeof(shm_buf));
114 _ASSERT(handle != NULL, MEM_EOUT_OF_SYSTEM_MEMORY);
115
116 /* Parameter Buffers : Allocate from Shared Memory considering MemHeader*/
117 SHM_alloc(sz + sizeof(MemHeader), handle);
118
119 h = (MemHeader *)handle->vir_addr;
120 _ASSERT_AND_EXECUTE(h != NULL, MEM_EOUT_OF_SHMEMORY, free(handle));
121
122 h->size = sz;
123 h->ptr = handle;
124 memset(H2P(h), 0, sz);
125 return (H2P(h));
126 }
127EXIT:
128 return (NULL);
129}
130
131/* memory_type is not added if MemHeader is used for Tiler Buffers */
132void memplugin_free(void *ptr, mem_type memory_type)
133{
134 shm_buf *handle;
135 mem_error_status eError = MEM_EOK;
136
137 _ASSERT(ptr != NULL, MEM_EINVALID_INPUT);
138 _ASSERT((memory_type < MEM_MAX) && (memory_type >= TILER_1D_BUFFER), MEM_EINVALID_INPUT);
139
140 if( memory_type == TILER_1D_BUFFER ) {
141 MemMgr_Free(P2H(ptr));
142 } else if( memory_type == SHARED_MEMORY_BUFFER ) {
143 handle = (P2H(ptr))->ptr;
144 SHM_release(handle);
145 free(handle);
146 } else {
147 ERROR("Tiler 2D Allocation/Free not implemented");
148 }
149EXIT:;
150}
151
152void *memplugin_share(void *ptr, mem_type memory_type)
153{
154 /* No Userspace Virtual pointers to DMA BUF Handles conversion required*/
155 /* Do nothing */
156 return (ptr);
157}
158
diff --git a/nto/Makefile b/nto/Makefile
new file mode 100644
index 0000000..5323e99
--- /dev/null
+++ b/nto/Makefile
@@ -0,0 +1,2 @@
1LIST=CPU
2include recurse.mk
diff --git a/nto/README.txt b/nto/README.txt
new file mode 100644
index 0000000..bf43f03
--- /dev/null
+++ b/nto/README.txt
@@ -0,0 +1 @@
This Directory is QNX/Neutrino specific.
diff --git a/nto/arm/Makefile b/nto/arm/Makefile
new file mode 100644
index 0000000..a5e4d9b
--- /dev/null
+++ b/nto/arm/Makefile
@@ -0,0 +1,2 @@
1LIST=VARIANT
2include recurse.mk
diff --git a/nto/arm/a.le.v7/Makefile b/nto/arm/a.le.v7/Makefile
new file mode 100644
index 0000000..9d6821f
--- /dev/null
+++ b/nto/arm/a.le.v7/Makefile
@@ -0,0 +1 @@
include ../../../common.mk
diff --git a/nto/arm/so.le.v7/Makefile b/nto/arm/so.le.v7/Makefile
new file mode 100644
index 0000000..9d6821f
--- /dev/null
+++ b/nto/arm/so.le.v7/Makefile
@@ -0,0 +1 @@
include ../../../common.mk
diff --git a/nto/qconf-override.mk b/nto/qconf-override.mk
new file mode 100644
index 0000000..cf6c23c
--- /dev/null
+++ b/nto/qconf-override.mk
@@ -0,0 +1,9 @@
1# If you wish to override the values of some of the macros defined in qconfig.mk
2# without modifying the contents of the file, set the QCONF_OVERRIDE environment
3# variable to this file (which will be included at the end of the qconfig.mk file)
4# and override the qconfig.mk macros here.
5
6# Override INSTALL_ROOT_nto macro
7INSTALL_ROOT ?= $(shell pwd)
8INSTALL_ROOT_nto := $(INSTALL_ROOT)
9USE_INSTALL_ROOT = 1
diff --git a/test_qnx/Makefile b/test_qnx/Makefile
new file mode 100644
index 0000000..5323e99
--- /dev/null
+++ b/test_qnx/Makefile
@@ -0,0 +1,2 @@
1LIST=CPU
2include recurse.mk
diff --git a/test_qnx/arm/Makefile b/test_qnx/arm/Makefile
new file mode 100644
index 0000000..6a18617
--- /dev/null
+++ b/test_qnx/arm/Makefile
@@ -0,0 +1,8 @@
1LIST=VARIANT
2ifndef QRECURSE
3QRECURSE=recurse.mk
4ifdef QCONFIG
5QRDIR=$(dir $(QCONFIG))
6endif
7endif
8include $(QRDIR)$(QRECURSE)
diff --git a/test_qnx/arm/le.v7/Makefile b/test_qnx/arm/le.v7/Makefile
new file mode 100644
index 0000000..cc39927
--- /dev/null
+++ b/test_qnx/arm/le.v7/Makefile
@@ -0,0 +1 @@
include ../../common.mk
diff --git a/test_qnx/common.mk b/test_qnx/common.mk
new file mode 100644
index 0000000..be901c0
--- /dev/null
+++ b/test_qnx/common.mk
@@ -0,0 +1,50 @@
1###################### QNX DCE Test App Build Config #######################
2
3#### Include qconfig.mk
4ifndef QCONFIG
5QCONFIG=qconfig.mk
6endif
7include $(QCONFIG)
8
9define PINFO
10PINFO DESCRIPTION=DCE Test
11endef
12
13NAME = dce_test
14INSTALLDIR = bin
15
16# Different tool versions can easily be programmed by defining below variables
17# in your environment.
18CEVERSION ?= codec_engine_3_23_00_07
19FCVERSION ?= framework_components_3_23_03_17
20XDAISVERSION ?= xdais_7_23_00_06
21XDCVERSION ?= xdctools_3_25_00_48
22IPCHEADERS ?= $(INSTALL_ROOT_nto)
23IVAHDCODECS ?= ipumm/extrel/ti/ivahd_codecs
24
25# Generate the full package paths for tools
26CEPROD = $(TIVIDEOTOOLSROOT)/$(CEVERSION)
27FCPROD = $(TIVIDEOTOOLSROOT)/$(FCVERSION)
28XDAISPROD = $(TITOOLSROOT)/$(XDAISVERSION)
29XDCPROD = $(TITOOLSROOT)/$(XDCVERSION)
30
31#Add extra include path
32EXTRA_INCVPATH += $(CEPROD)/packages
33EXTRA_INCVPATH += $(FCPROD)/packages
34EXTRA_INCVPATH += $(XDAISPROD)/packages
35EXTRA_INCVPATH += $(XDCPROD)/packages
36EXTRA_INCVPATH += $(IVAHDCODECS)/packages
37EXTRA_INCVPATH += $(PROJECT_ROOT)/../
38EXTRA_INCVPATH += $(IPCHEADERS)/usr/include/memmgr
39EXTRA_INCVPATH += $(IPCHEADERS)/usr/include/ti/syslink
40EXTRA_INCVPATH += $(IPCHEADERS)/usr/include
41
42CCOPTS+=-g -O0 -Dxdc_target_types__=qnx/targets/arm/std.h
43
44EXTRA_LIBVPATH += $(PROJECT_ROOT)/../nto/arm/so.le.v7 \
45 $(INSTALL_ROOT_nto)/armle-v7/usr/lib
46
47LDOPTS+= -ldce -lmemmgr -ltilerusr -lsyslink_client -lsharedmemallocator
48
49include $(MKFILES_ROOT)/qtargets.mk
50
diff --git a/test_qnx/dce_test.c b/test_qnx/dce_test.c
new file mode 100644
index 0000000..805b240
--- /dev/null
+++ b/test_qnx/dce_test.c
@@ -0,0 +1,1437 @@
1/*
2 * Copyright (c) 2013, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32#include <xdc/std.h>
33#include <stdlib.h>
34#include <string.h>
35#include <stdio.h>
36#include <stdint.h>
37#include <sys/types.h>
38#include <sys/stat.h>
39#include <sys/time.h>
40#include <fcntl.h>
41#include <errno.h>
42#include <time.h>
43#include <sys/mman.h>
44
45#include <tilermem.h>
46#include <memmgr.h>
47#include <xdc/std.h>
48#include <ti/sdo/ce/Engine.h>
49#include <ti/sdo/ce/video3/viddec3.h>
50#include <ti/sdo/codecs/h264vdec/ih264vdec.h>
51#include <ti/sdo/codecs/mpeg4vdec/impeg4vdec.h>
52#include <ti/sdo/codecs/vc1vdec/ivc1vdec.h>
53#include <ti/sdo/codecs/jpegvdec/ijpegvdec.h>
54#ifdef ENABLE_MPEG2
55#include <ti/sdo/codecs/mpeg2vdec/impeg2vdec.h>
56#endif
57#include "ti/shmemallocator/SharedMemoryAllocatorUsr.h"
58#include "libdce.h"
59
60#define OMAP5
61
62#define PRINT_DEBUG
63#define ERROR(FMT, ...) printf("%s:%d:\t%s\terror: " FMT "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
64// enable below to print debug information
65#ifdef PRINT_DEBUG
66#define DEBUG(FMT, ...) printf("%s:%d:\t%s\tdebug: " FMT "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
67#else
68#define DEBUG(FMT, ...)
69#endif
70#define INFO(FMT, ...) printf("%s:%d:\t%s\tinfo: " FMT "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
71#define MIN(a, b) (((a) < (b)) ? (a) : (b))
72
73/* align x to next highest multiple of 2^n */
74#define ALIGN2(x, n) (((x) + ((1 << (n)) - 1)) & ~((1 << (n)) - 1))
75
76// Profile the init and decode calls
77//#define PROFILE_TIME
78
79enum {
80 IVAHD_AVC1_DECODE,
81 IVAHD_H264_DECODE,
82 IVAHD_MP4V_DECODE,
83 IVAHD_S263_DECODE,
84 IVAHD_VC1AP_DECODE,
85 IVAHD_VC1SMP_DECODE,
86 IVAHD_VP6V_DECODE,
87 IVAHD_MP2V_DECODE,
88 IVAHD_JPEGV_DECODE
89};
90
91/*
92 * A very simple VIDDEC3 client which will decode h264 frames (one per file),
93 * and write out raw (unstrided) nv12 frames (one per file).
94 */
95
96int width, height, padded_width, padded_height, num_buffers, tiler;
97Engine_Handle engine = NULL;
98VIDDEC3_Handle codec = NULL;
99VIDDEC3_Params *params = NULL;
100VIDDEC3_DynamicParams *dynParams = NULL;
101VIDDEC3_Status *status = NULL;
102XDM2_BufDesc *inBufs = NULL;
103XDM2_BufDesc *outBufs = NULL;
104VIDDEC3_InArgs *inArgs = NULL;
105VIDDEC3_OutArgs *outArgs = NULL;
106
107IH264VDEC_Params *h264_params = NULL;
108IH264VDEC_DynamicParams *h264_dynParams = NULL;
109IH264VDEC_Status *h264_status = NULL;
110
111IMPEG4VDEC_Params *mpeg4_params = NULL;
112IMPEG4VDEC_DynamicParams *mpeg4_dynParams = NULL;
113IMPEG4VDEC_Status *mpeg4_status = NULL;
114
115IVC1VDEC_Params *vc1_params = NULL;
116IVC1VDEC_DynamicParams *vc1_dynParams = NULL;
117IVC1VDEC_Status *vc1_status = NULL;
118
119IJPEGVDEC_Params *mjpeg_params = NULL;
120IJPEGVDEC_DynamicParams *mjpeg_dynParams = NULL;
121IJPEGVDEC_Status *mjpeg_status = NULL;
122#ifdef ENABLE_MPEG2
123IMPEG2VDEC_Params *mpeg2_params = NULL;
124IMPEG2VDEC_DynamicParams *mpeg2_dynParams = NULL;
125IMPEG2VDEC_Status *mpeg2_status = NULL;
126#endif
127unsigned int frameSize[64000]; /* Buffer for keeping frame sizes */
128static int input_offset = 0;
129
130/*! Padding for width as per Codec Requirement */
131#define PADX_H264 32
132#define PADX_MPEG4 32
133#define PADX_VC1 32
134/*! Padding for height as per Codec Requirement */
135#define PADY_H264 24
136#define PADY_MPEG4 32
137#define PADY_VC1 40
138
139static void *tiler_alloc(int width, int height)
140{
141 int dimensions;
142 void *bufPtr = NULL;
143 MemAllocBlock block;
144 MemAllocBlock blocks[2];
145
146 memset(&block, 0, sizeof(MemAllocBlock));
147 memset(blocks, 0, sizeof(MemAllocBlock) * 2);
148
149 if( !height ) {
150 DEBUG("tiler alloc 1D allocation width=%d", width);
151 /* 1d allocation: */
152 dimensions = 1;
153
154 block.pixelFormat = PIXEL_FMT_PAGE;
155 block.dim.len = width;
156 block.stride = 0;
157
158 bufPtr = MemMgr_Alloc(&block, dimensions);
159 } else {
160 DEBUG("tiler alloc 2D allocation width=%d height=%d", width, height);
161 /* 2d allocation: */
162 dimensions = 2;
163 blocks[0].pixelFormat = PIXEL_FMT_8BIT;
164 blocks[0].dim.area.width = width;
165 blocks[0].dim.area.height = height;
166 blocks[0].stride = 0;
167
168 blocks[1].pixelFormat = PIXEL_FMT_16BIT;
169 blocks[1].dim.area.width = width >> 1;
170 blocks[1].dim.area.height = height >> 1;
171 blocks[1].stride = 0;
172
173 bufPtr = MemMgr_Alloc(blocks, dimensions);
174 }
175 DEBUG("tiler alloc return bufPtr %p", bufPtr);
176
177 return (bufPtr);
178}
179
180/* ************************************************************************* */
181/* utilities to allocate/manage 2d output buffers */
182
183typedef struct OutputBuffer OutputBuffer;
184
185struct OutputBuffer {
186 char *buf; /* virtual address for local access, 4kb stride */
187 uint32_t y, uv; /* virtual address of Y and UV for remote access */
188 OutputBuffer *next; /* next free buffer */
189 bool tiler;
190 uint32_t len;
191 shm_buf shmBuf;
192};
193
194static XDAS_Int16
195get_mem_type (uint32_t paddr)
196{
197 if((0x60000000 <= paddr) && (paddr < 0x68000000)) {
198 return (XDM_MEMTYPE_TILED8);
199 }
200 if((0x68000000 <= paddr) && (paddr < 0x70000000)) {
201 return (XDM_MEMTYPE_TILED16);
202 }
203 if((0x70000000 <= paddr) && (paddr < 0x78000000)) {
204 return (XDM_MEMTYPE_TILED32);
205 }
206 if((0x78000000 <= paddr) && (paddr < 0x80000000)) {
207 return (XDM_MEMTYPE_RAW);
208 }
209 return (-1);
210}
211
212/* list of free buffers, not locked by codec! */
213static OutputBuffer *head = NULL;
214
215#if 0
216/*! @brief Start address of DDR region for 1GB RAM */
217#define DDR_1G_ADDRESS_START 0x80000000
218/*! @brief End address of DDR region for 1GB RAM */
219#define DDR_1G_ADDRESS_END 0xBFFFFFFF
220#define DDR_1G_DUCATI_OFFSET 0x40000000
221
222/*! @brief Start address of DDR region for 2GB RAM */
223#define DDR_2G_ADDRESS_START 0xC0000000
224/*! @brief End address of DDR region for 2GB RAM */
225#define DDR_2G_ADDRESS_END 0xFFFFFFFF
226#define DDR_2G_DUCATI_OFFSET 0xA0000000
227
228static Int
229SysLinkMemUtils_translateAddr (UInt32 physAddr)
230{
231 Int ret = 0;
232
233 if( physAddr >= DDR_1G_ADDRESS_START && physAddr <= DDR_1G_ADDRESS_END ) {
234 ret = physAddr + DDR_1G_DUCATI_OFFSET;
235 } else if( physAddr >= DDR_2G_ADDRESS_START && physAddr <= DDR_2G_ADDRESS_END ) {
236 ret = physAddr - DDR_2G_DUCATI_OFFSET;
237 }
238
239 return (ret);
240}
241
242#endif
243
244int output_allocate(XDM2_BufDesc *outBufs, int cnt,
245 int width, int height, int stride)
246{
247 int tw, th;
248
249 outBufs->numBufs = 2;
250
251 if( stride != 4096 ) {
252 /* non-2d allocation! */
253 int size_y = stride * height;
254 int size_uv = stride * height / 2;
255 tw = size_y + size_uv;
256 th = 0;
257 outBufs->descs[0].memType = XDM_MEMTYPE_TILEDPAGE;
258 outBufs->descs[0].bufSize.bytes = size_y;
259 outBufs->descs[1].memType = XDM_MEMTYPE_TILEDPAGE;
260 outBufs->descs[1].bufSize.bytes = size_uv;
261 } else {
262 tw = width;
263 th = height;
264 outBufs->descs[0].memType = XDM_MEMTYPE_TILED8;
265 outBufs->descs[0].bufSize.tileMem.width = width;
266 outBufs->descs[0].bufSize.tileMem.height = height;
267 outBufs->descs[1].memType = XDM_MEMTYPE_TILED16;
268 outBufs->descs[1].bufSize.tileMem.width = width; /* UV interleaved width is same a Y */
269 outBufs->descs[1].bufSize.tileMem.height = height / 2;
270 }
271
272 while( cnt ) {
273 OutputBuffer *buf = calloc(sizeof(OutputBuffer), 1);
274
275 DEBUG(" ----------------- create TILER buf 0x%x --------------------", (unsigned int)buf);
276
277 buf->buf = tiler_alloc(tw, th);
278 if( buf->buf ) {
279 buf->y = (uint32_t) buf->buf;
280 buf->uv = (uint32_t)(buf->buf + (height * stride));
281
282 DEBUG("cnt=%d buf=%p, y=%08x, uv=%08x", cnt, buf, buf->y, buf->uv);
283
284 buf->tiler = TRUE;
285 buf->next = head;
286 head = buf;
287 } else {
288 ERROR(" ---------------- tiler_alloc failed --------------------");
289 free(buf);
290 return (-EAGAIN);
291 }
292 cnt--;
293 }
294
295 return (0);
296}
297
298int output_allocate_nonTiler(XDM2_BufDesc *outBufs, int cnt,
299 int width, int height, int stride)
300{
301 int tw;
302 XDAS_Int16 y_type, uv_type;
303
304 outBufs->numBufs = 2;
305
306 while( cnt ) {
307 OutputBuffer *buf = calloc(sizeof(OutputBuffer), 1);
308
309 DEBUG(" ----------------- create nonTILER buf 0x%x --------------------", (unsigned int)buf);
310 int size_y = width * height;
311 int size_uv = width * height * 1 / 2;
312 tw = size_y + size_uv;
313
314 // Allocation through mmap
315 uint64_t *vaddr;
316 int32_t ret, len = 0;
317 int64_t paddr = 0;
318 uint32_t uv_addr;
319
320 //vaddr = mmap64(0, tw, PROT_NOCACHE | PROT_READ | PROT_WRITE, MAP_ANON | MAP_PHYS | MAP_SHARED, NOFD, 0);
321 ret = SHM_alloc(tw, &buf->shmBuf);
322 //if (vaddr == MAP_FAILED) {
323 if( ret < 0 ) {
324 //ERROR("Failed to do memory mapping\n");
325 ERROR("Failed to alloc shmem buffer\n");
326 free(buf);
327 return (-ENOMEM);
328 }
329 vaddr = (uint64_t *)buf->shmBuf.vir_addr;
330
331 // Make sure the memory is contiguous
332 ret = mem_offset64(vaddr, NOFD, (size_t) tw, &paddr, (size_t *) &len);
333 if( ret ) {
334 ERROR("Failed to check memory contiguous ret %d errno %d\n", ret, errno);
335 //munmap(vaddr, tw);
336 SHM_release(&buf->shmBuf);
337 free(buf);
338 return (-ENOMEM);
339 } else if( len != (tw)) {
340 ERROR("Failed to check len %d != %d\n", len, tw);
341 //munmap(vaddr, tw);
342 SHM_release(&buf->shmBuf);
343 free(buf);
344 return (-ENOMEM);
345 }
346
347 buf->buf = (char *) vaddr;
348 buf->y = (uint32_t)vaddr;
349 uv_addr = (uint32_t) vaddr + (width * height);
350 buf->uv = uv_addr;
351
352 DEBUG("cnt=%d nonTILER buf=%p, y=%08x, uv=%08x paddr=%08x", cnt, buf, buf->y, buf->uv, (unsigned int) paddr);
353
354 y_type = get_mem_type(buf->y);
355 uv_type = get_mem_type(buf->uv);
356
357 if((y_type < 0) || (uv_type < 0)) {
358 DEBUG("non TILER buffer address translation buf->y %x buf->uv %x", buf->y, buf->uv);
359 //buf->y = SysLinkMemUtils_translateAddr(buf->y);
360 //buf->uv = SysLinkMemUtils_translateAddr(buf->uv);
361 y_type = XDM_MEMTYPE_RAW;
362 uv_type = XDM_MEMTYPE_RAW;
363 DEBUG("buf->y %x buf->uv %x", buf->y, buf->uv);
364 if( !buf->y || !buf->uv ) {
365 //munmap(vaddr, tw);
366 SHM_release(&buf->shmBuf);
367 free(buf);
368 return (-ENOMEM);
369 }
370 }
371
372 buf->next = head;
373 buf->tiler = FALSE;
374 buf->len = tw;
375 head = buf;
376
377 cnt--;
378 }
379
380 if((y_type == XDM_MEMTYPE_RAW) && (uv_type == XDM_MEMTYPE_RAW)) {
381 outBufs->descs[0].memType = y_type;
382 outBufs->descs[0].bufSize.bytes = width * height;
383 outBufs->descs[1].memType = uv_type;
384 outBufs->descs[1].bufSize.bytes = width * height * 1 / 2;
385 }
386
387 return (0);
388}
389
390void output_free(void)
391{
392 OutputBuffer *buf = head;
393
394 while((buf=head)) {
395 if( buf->tiler ) {
396 MemMgr_Free(buf->buf);
397 } else {
398 //munmap(buf->buf, buf->len);
399 SHM_release(&buf->shmBuf);
400 }
401 head = buf->next;
402 free(buf);
403 }
404}
405
406OutputBuffer *output_get(void)
407{
408 OutputBuffer *buf = head;
409
410 if( buf ) {
411 head = buf->next;
412 }
413 DEBUG("output_get: %p", buf);
414 return (buf);
415}
416
417void output_release(OutputBuffer *buf)
418{
419 DEBUG("output_release: %p", buf);
420 buf->next = head;
421 head = buf;
422}
423
424/* ************************************************************************* */
425
426/* get file path.. return path is only valid until next time this is called */
427static const char *get_path(const char *pattern, int cnt)
428{
429 static int len = 0;
430 static char *path = NULL;
431
432 /* It would be better to not assume the pattern doesn't expand to
433 * less than 10 chars it's original length..
434 */
435 if((strlen(pattern) + 10) > len ) {
436 len = strlen(pattern) + 10;
437 path = realloc(path, len);
438 }
439
440 snprintf(path, len - 1, pattern, cnt);
441
442 return (path);
443}
444
445/* helper to read one frame of input */
446int read_input(const char *pattern, int cnt, char *input)
447{
448 int sz = 0, n = 0;
449 const char *path = get_path(pattern, cnt);
450 int fd = open(path, O_RDONLY);
451
452 //DEBUG("Open file fd %d errno %d", fd, errno);
453 /* if we can't find the file, then at the end of stream */
454 if( fd < 0 ) {
455 DEBUG("open input file failed");
456 return (0);
457 }
458
459 if( frameSize[cnt] && (frameSize[cnt] != -1)) {
460 lseek(fd, input_offset, SEEK_SET);
461 n = read(fd, input, frameSize[cnt]);
462 //DEBUG("reading input frameSize[%d] = n =%d", cnt, n);
463 sz += n;
464 input_offset += n;
465 } else if((frameSize[cnt] == -1)) {
466 // This happens to indicate flush command
467 DEBUG("Flush requested from file size -1,frameSize[%d] is %d", cnt, frameSize[cnt]);
468 sz = -1;
469 }
470
471 close(fd);
472
473 DEBUG("sz=%d", sz);
474 return (sz);
475}
476
477/* helper to write one frame of output */
478int write_output(const char *pattern, int cnt, char *y, char *uv, int stride)
479{
480 int sz = 0, n, i;
481 const char *path = get_path(pattern, cnt);
482 int fd = open(path, O_WRONLY | O_CREAT | O_APPEND, 0644);
483
484 if( fd < 0 ) {
485 ERROR("could open output file: %s (%d)", path, errno);
486 return (0);
487 }
488
489 for( i = 0; i < height; i++ ) {
490 char *p = y;
491 int len = width;
492
493 while( len && ((n = write(fd, p, len)) > 0)) {
494 sz += n;
495 p += n;
496 len -= n;
497 }
498
499 if( n < 0 ) {
500 ERROR("couldn't write to output file: (%d)", errno);
501 break;
502 }
503 y += stride;
504 }
505
506 if( n >= 0 ) {
507 for( i = 0; i < height / 2; i++ ) {
508 char *p = uv;
509 int len = width;
510
511 while( len && ((n = write(fd, p, len)) > 0)) {
512 sz += n;
513 p += n;
514 len -= n;
515 }
516
517 if( n < 0 ) {
518 ERROR("couldn't write to output file: (%d)", errno);
519 break;
520 }
521 uv += stride;
522 }
523 }
524
525 close(fd);
526
527 return (sz);
528}
529
530#ifdef PROFILE_TIME
531/* for timing in microsecond */
532uint64_t mark_microsecond(uint64_t *last)
533{
534#if 0
535 struct timespec time;
536 uint64_t t1 = 0;
537
538 clock_gettime(CLOCK_REALTIME, &time);
539 t1 = timespec2nsec(&time);
540 t1 = t1 / 1000;
541#else
542 uint64_t t1 = 0;
543
544 t1 = ClockCycles();
545 t1 = t1 * 1000000000 / SYSPAGE_ENTRY(qtime)->cycles_per_sec;
546 t1 = t1 / 1000;
547#endif
548 if( last ) {
549 return (t1 - *last);
550 }
551 return (t1);
552}
553
554#endif
555//#define DUMPINPUTDATA
556
557#ifdef DUMPINPUTDATA
558FILE *inputDump;
559#endif
560
561#define VERSION_SIZE 128
562static char version_buffer[VERSION_SIZE];
563
564/* decoder body */
565int main(int argc, char * *argv)
566{
567 Engine_Error ec;
568 XDAS_Int32 err;
569 char *input = NULL;
570 char *in_pattern, *out_pattern, *frameData;
571 int in_cnt = 0, out_cnt = 0;
572 int oned, stride;
573 unsigned int frameCount = 0;
574 FILE *frameFile;
575 unsigned char frameinput[10] = { "\0" };
576 int eof = 0;
577 int ivahd_decode_type;
578 char vid_codec[10];
579 char tilerbuffer[10];
580 unsigned int codec_switch = 0;
581 unsigned int vc1_flush = 0;
582 Bool outBufsInUse = FALSE;
583
584#ifdef PROFILE_TIME
585 uint64_t init_start_time = 0;
586 uint64_t codec_process_time = 0;
587 uint64_t total_init_time = 0;
588 uint64_t output_alloc_time = 0;
589#endif
590
591#if 0
592 int loop = 0;
593
594 while( loop == 0 ) {
595 loop = 0;
596 }
597
598#endif
599
600 if((argc >= 2) && !strcmp(argv[1], "-1")) {
601 oned = TRUE;
602 argc--;
603 argv++;
604 } else {
605 oned = FALSE;
606 }
607
608 if( argc != 8 ) {
609 printf("usage: %s width height framefile inpattern outpattern codec tilerbuffer\n", argv[0]);
610 printf("example: %s 320 240 frame.txt in.h264 out.yuv h264 tiler\n", argv[0]);
611 printf("example: %s 640 480 frame.txt in.m4v out.yuv mpeg4 nontiler\n", argv[0]);
612 printf("example: %s 720 480 frame.txt in.vc1 out.yuv vc1ap tiler\n", argv[0]);
613 printf("example: %s 320 240 frame.txt in.vc1 out.yuv vc1smp nontiler\n", argv[0]);
614 printf("example: %s 1280 720 frame.txt in.bin out.yuv mjpeg tiler\n", argv[0]);
615 printf("example: %s 1920 1088 frame.txt in.bin out.yuv mpeg2 nontiler\n", argv[0]);
616 printf("Currently supported codecs: h264, mpeg4, vc1ap, vc1smp, mjpeg, mpeg2\n");
617 return (1);
618 }
619
620 /* error checking? */
621 width = atoi(argv[1]);
622 height = atoi(argv[2]);
623 frameData = argv[3];
624 in_pattern = argv[4];
625 out_pattern = argv[5];
626 strcpy(vid_codec, argv[6]);
627 strcpy(tilerbuffer, argv[7]);
628
629 printf("Selected codec: %s\n", vid_codec);
630 printf("Selected buffer: %s\n", tilerbuffer);
631
632 enum {
633 DCE_TEST_H264 = 1,
634 DCE_TEST_MPEG4 = 2,
635 DCE_TEST_VC1SMP = 3,
636 DCE_TEST_VC1AP = 4,
637 DCE_TEST_MJPEG = 5,
638 DCE_TEST_MPEG2 = 6
639 };
640
641 if((!(strcmp(vid_codec, "h264")))) {
642 ivahd_decode_type = IVAHD_H264_DECODE;
643 codec_switch = DCE_TEST_H264;
644
645 } else if((!(strcmp(vid_codec, "mpeg4")))) {
646 ivahd_decode_type = IVAHD_MP4V_DECODE;
647 codec_switch = DCE_TEST_MPEG4;
648
649 } else if((!(strcmp(vid_codec, "vc1smp")))) {
650 ivahd_decode_type = IVAHD_VC1SMP_DECODE;
651 codec_switch = DCE_TEST_VC1SMP;
652 vc1_flush = 1;
653
654 } else if((!(strcmp(vid_codec, "vc1ap")))) {
655 ivahd_decode_type = IVAHD_VC1AP_DECODE;
656 codec_switch = DCE_TEST_VC1AP;
657 vc1_flush = 1;
658
659 } else if((!(strcmp(vid_codec, "mjpeg")))) {
660 ivahd_decode_type = IVAHD_JPEGV_DECODE;
661 codec_switch = DCE_TEST_MJPEG;
662
663 } else if((!(strcmp(vid_codec, "mpeg2")))) {
664 ivahd_decode_type = IVAHD_MP2V_DECODE;
665 codec_switch = DCE_TEST_MPEG2;
666
667 } else {
668 printf("No valid codec entry. Please use: h264, mpeg4, vc1ap, vc1smp, mjpeg or mpeg2\n");
669 return (1);
670 }
671
672 DEBUG("Storing frame size data");
673 frameFile = fopen(frameData, "rb");
674 DEBUG("frameFile open %p errno %d", frameFile, errno);
675 if( frameFile == NULL ) {
676 DEBUG("Opening framesize file FAILED");
677 }
678
679 /* Read the frame Size from the frame size file */
680 while( NULL != fgets((char *)frameinput, 10, frameFile)) {
681 frameSize[frameCount] = atoi((char *)frameinput);
682 //DEBUG("frameSize[%d] = %d \n", frameCount, frameSize[frameCount]);
683
684 if( frameCount > 64000 ) {
685 DEBUG("Num Frames %d exceeded MAX limit %d \n", frameCount, 64000);
686 goto out;
687 }
688 frameCount++;
689 }
690
691 DEBUG("Num Frames is %d width=%d, height=%d", frameCount, width, height);
692
693 /* calculate output buffer parameters: */
694 width = ALIGN2(width, 4); /* round up to MB */
695 height = ALIGN2(height, 4); /* round up to MB */
696
697 switch( codec_switch ) {
698 case DCE_TEST_H264 :
699 padded_width = ALIGN2(width + (2 * PADX_H264), 7);
700 padded_height = height + 4 * PADY_H264;
701 // Some clips don't have enough buffers based on N+3 formula
702 // Need sps->num_ref_frames data to match filter precisely
703 //num_buffers = 2 * (MIN(16, 32768 / ((width / 16) * (height / 16)))) + 1;
704 num_buffers = (MIN(16, 32768 / ((width / 16) * (height / 16)))) + 3;
705 break;
706 case DCE_TEST_MPEG4 :
707 padded_width = ALIGN2(width + PADX_MPEG4, 7);
708 padded_height = height + PADY_MPEG4;
709 num_buffers = 8;
710 break;
711 case DCE_TEST_VC1SMP :
712 case DCE_TEST_VC1AP :
713 padded_width = ALIGN2(width + (2 * PADX_VC1), 7);
714 padded_height = (ALIGN2(height / 2, 4) * 2) + 4 * PADY_VC1;
715 num_buffers = 5;
716 break;
717 case DCE_TEST_MJPEG :
718 padded_width = ALIGN2(width, 4);
719 padded_height = ALIGN2(height, 4);
720 num_buffers = 5;
721 break;
722 case DCE_TEST_MPEG2 :
723 padded_width = ALIGN2(width, 7);
724 padded_height = height;
725 num_buffers = 4;
726 break;
727 }
728
729 if( oned ) {
730 stride = padded_width;
731 } else {
732 stride = 4096;
733 }
734
735 DEBUG("padded_width=%d, padded_height=%d, stride=%d, num_buffers=%d",
736 padded_width, padded_height, stride, num_buffers);
737#ifdef PROFILE_TIME
738 init_start_time = mark_microsecond(NULL);
739#endif
740 engine = Engine_open("ivahd_vidsvr", NULL, &ec);
741
742 if( !engine ) {
743 ERROR("fail");
744 goto out;
745 }
746
747 DEBUG("Engine_open successful engine=%p", engine);
748
749 switch( codec_switch ) {
750 case DCE_TEST_H264 :
751 params = dce_alloc(sizeof(IH264VDEC_Params));
752 if( !params ) {
753 ERROR("dce_alloc fail");
754 goto out;
755 }
756 params->size = sizeof(IH264VDEC_Params);
757 params->maxBitRate = 10000000;
758 params->displayDelay = IVIDDEC3_DISPLAY_DELAY_AUTO;
759 params->numOutputDataUnits = 0;
760 params->maxWidth = width;
761 break;
762 case DCE_TEST_MPEG4 :
763 params = dce_alloc(sizeof(IMPEG4VDEC_Params));
764 if( !params ) {
765 ERROR("dce_alloc fail");
766 goto out;
767 }
768 params->size = sizeof(IMPEG4VDEC_Params);
769 params->maxBitRate = 10000000;
770 params->displayDelay = IVIDDEC3_DISPLAY_DELAY_1;
771 params->numOutputDataUnits = 0;
772 params->maxWidth = width;
773 break;
774 case DCE_TEST_VC1SMP :
775 case DCE_TEST_VC1AP :
776 params = dce_alloc(sizeof(IVC1VDEC_Params));
777 if( !params ) {
778 ERROR("dce_alloc fail");
779 goto out;
780 }
781 params->size = sizeof(IVC1VDEC_Params);
782 params->maxBitRate = 45000000;
783 params->displayDelay = IVIDDEC3_DISPLAY_DELAY_1;
784 params->numOutputDataUnits = 0;
785 params->maxWidth = width;
786 break;
787 case DCE_TEST_MJPEG :
788 params = dce_alloc(sizeof(IJPEGVDEC_Params));
789 if( !params ) {
790 ERROR("dce_alloc fail");
791 goto out;
792 }
793 params->size = sizeof(IJPEGVDEC_Params);
794 params->maxBitRate = 10000000;
795 params->displayDelay = IVIDDEC3_DISPLAY_DELAY_1;
796 params->numOutputDataUnits = 1;
797 params->maxWidth = width;
798 break;
799#ifdef ENABLE_MPEG2
800 case DCE_TEST_MPEG2 :
801 params = dce_alloc(sizeof(IMPEG2VDEC_Params));
802 if( !params ) {
803 ERROR("dce_alloc fail");
804 goto out;
805 }
806 params->size = sizeof(IMPEG2VDEC_Params);
807 params->maxBitRate = 10000000;
808 params->displayDelay = IVIDDEC3_DISPLAY_DELAY_1;
809 params->numOutputDataUnits = 0;
810 params->maxWidth = padded_width;
811 break;
812#endif
813 }
814
815 params->maxHeight = height;
816 params->maxFrameRate = 30000;
817 params->dataEndianness = XDM_BYTE;
818 params->forceChromaFormat = XDM_YUV_420SP;
819 params->operatingMode = IVIDEO_DECODE_ONLY;
820 //params->displayDelay = IVIDDEC3_DECODE_ORDER;
821 params->displayBufsMode = IVIDDEC3_DISPLAYBUFS_EMBEDDED;
822 params->inputDataMode = IVIDEO_ENTIREFRAME;
823 params->metadataType[0] = IVIDEO_METADATAPLANE_NONE;
824 params->metadataType[1] = IVIDEO_METADATAPLANE_NONE;
825 params->metadataType[2] = IVIDEO_METADATAPLANE_NONE;
826 params->outputDataMode = IVIDEO_ENTIREFRAME;
827 params->numInputDataUnits = 0;
828 params->errorInfoMode = IVIDEO_ERRORINFO_OFF;
829
830 DEBUG("dce_alloc VIDDEC3_Params successful params=%p", params);
831
832 switch( codec_switch ) {
833 case DCE_TEST_H264 :
834 h264_params = (IH264VDEC_Params *) params;
835 h264_params->dpbSizeInFrames = IH264VDEC_DPB_NUMFRAMES_AUTO;
836 h264_params->pConstantMemory = 0;
837 h264_params->presetLevelIdc = IH264VDEC_LEVEL41;
838 h264_params->errConcealmentMode = IH264VDEC_APPLY_CONCEALMENT;
839 h264_params->temporalDirModePred = TRUE;
840 h264_params->detectCabacAlignErr = IH264VDEC_DISABLE_CABACALIGNERR_DETECTION;
841
842 DEBUG("dce_alloc VIDDEC3_Params successful h264_params=%p", h264_params);
843
844 err = msync((Ptr)h264_params, sizeof(IH264VDEC_Params), MS_CACHE_ONLY | MS_SYNC);
845
846 codec = VIDDEC3_create(engine, "ivahd_h264dec", (VIDDEC3_Params *)h264_params);
847 break;
848
849 case DCE_TEST_MPEG4 :
850 mpeg4_params = (IMPEG4VDEC_Params *) params;
851 mpeg4_params->outloopDeBlocking = TRUE;
852 mpeg4_params->sorensonSparkStream = FALSE;
853 mpeg4_params->errorConcealmentEnable = FALSE;
854 mpeg4_params->debugTraceLevel = 0;
855 mpeg4_params->lastNFramesToLog = 0;
856 mpeg4_params->paddingMode = IMPEG4VDEC_DEFAULT_MODE_PADDING;
857
858 DEBUG("dce_alloc VIDDEC3_Params successful mpeg4_params=%p", mpeg4_params);
859
860 err = msync((Ptr)mpeg4_params, sizeof(IMPEG4VDEC_Params), MS_CACHE_ONLY | MS_SYNC);
861#ifdef OMAP5
862 codec = VIDDEC3_create(engine, "ivahd_mpeg4dec", (VIDDEC3_Params *)mpeg4_params);
863#else
864 codec = VIDDEC3_create(engine, "ivahd_mpeg4vdec", (VIDDEC3_Params *)mpeg4_params);
865#endif
866 break;
867
868 case DCE_TEST_VC1SMP :
869 case DCE_TEST_VC1AP :
870 vc1_params = (IVC1VDEC_Params *) params;
871
872 DEBUG("dce_alloc VIDDEC3_Params successful vc1_params=%p", vc1_params);
873
874 err = msync((Ptr)vc1_params, sizeof(IVC1VDEC_Params), MS_CACHE_ONLY | MS_SYNC);
875
876 codec = VIDDEC3_create(engine, "ivahd_vc1vdec", (VIDDEC3_Params *)vc1_params);
877 break;
878
879 case DCE_TEST_MJPEG :
880 mjpeg_params = (IJPEGVDEC_Params *) params;
881 mjpeg_params->ErrorConcealmentON = TRUE;
882 mjpeg_params->debugTraceLevel = 0;
883 mjpeg_params->lastNFramesToLog = 0;
884 mjpeg_params->sliceSwitchON = 0;
885 mjpeg_params->numSwitchPerFrame = 0;
886 mjpeg_params->numRestartMarkerPerSwitch = 0;
887
888 DEBUG("dce_alloc VIDDEC3_Params successful mjpeg_params=%p", mjpeg_params);
889
890 err = msync((Ptr)mjpeg_params, sizeof(IJPEGVDEC_Params), MS_CACHE_ONLY | MS_SYNC);
891
892 codec = VIDDEC3_create(engine, "ivahd_jpegvdec", (VIDDEC3_Params *)mjpeg_params);
893 break;
894#ifdef ENABLE_MPEG2
895 case DCE_TEST_MPEG2 :
896 mpeg2_params = (IMPEG2VDEC_Params *) params;
897 mpeg2_params->outloopDeBlocking = TRUE;
898 mpeg2_params->ErrorConcealmentON = FALSE;
899 mpeg2_params->debugTraceLevel = 0;
900 mpeg2_params->lastNFramesToLog = 0;
901
902 DEBUG("dce_alloc VIDDEC3_Params successful mpeg2_params=%p", mpeg2_params);
903
904 err = msync((Ptr)mpeg2_params, sizeof(IMPEG2VDEC_Params), MS_CACHE_ONLY | MS_SYNC);
905
906 codec = VIDDEC3_create(engine, "ivahd_mpeg2vdec", (VIDDEC3_Params *)mpeg2_params);
907 break;
908#endif
909 }
910
911 if( !codec ) {
912 ERROR("fail");
913 goto out;
914 }
915
916 DEBUG("VIDDEC3_create successful codec=%p", codec);
917
918 switch( codec_switch ) {
919 case DCE_TEST_H264 :
920 dynParams = dce_alloc(sizeof(IH264VDEC_DynamicParams));
921 dynParams->size = sizeof(IH264VDEC_DynamicParams);
922 break;
923 case DCE_TEST_MPEG4 :
924 dynParams = dce_alloc(sizeof(IMPEG4VDEC_DynamicParams));
925 dynParams->size = sizeof(IMPEG4VDEC_DynamicParams);
926 dynParams->lateAcquireArg = -1;
927 break;
928 case DCE_TEST_VC1SMP :
929 case DCE_TEST_VC1AP :
930 dynParams = dce_alloc(sizeof(IVC1VDEC_DynamicParams));
931 dynParams->size = sizeof(IVC1VDEC_DynamicParams);
932 dynParams->lateAcquireArg = -1;
933 break;
934 case DCE_TEST_MJPEG :
935 dynParams = dce_alloc(sizeof(IJPEGVDEC_DynamicParams));
936 dynParams->size = sizeof(IJPEGVDEC_DynamicParams);
937 dynParams->lateAcquireArg = -1;
938 break;
939#ifdef ENABLE_MPEG2
940 case DCE_TEST_MPEG2 :
941 dynParams = dce_alloc(sizeof(IMPEG2VDEC_DynamicParams));
942 dynParams->size = sizeof(IMPEG2VDEC_DynamicParams);
943 dynParams->lateAcquireArg = -1;
944 break;
945#endif
946 }
947
948 dynParams->decodeHeader = XDM_DECODE_AU;
949 /*Not Supported: Set default*/
950 dynParams->displayWidth = 0;
951 dynParams->frameSkipMode = IVIDEO_NO_SKIP;
952 dynParams->newFrameFlag = XDAS_TRUE;
953
954
955 //Testing XDM_GETVERSION
956 // NOT WORKING
957#if 0
958
959 switch( codec_switch ) {
960 case DCE_TEST_H264 :
961
962 DEBUG("dce_alloc IH264VDEC_DynamicParams successful dynParams=%p", dynParams);
963 h264_dynParams = (IH264VDEC_DynamicParams *) dynParams;
964 DEBUG("dce_alloc IH264VDEC_DynamicParams successful h264_dynParams=%p", h264_dynParams);
965
966 status = dce_alloc(sizeof(IH264VDEC_Status));
967 status->size = sizeof(IH264VDEC_Status);
968 DEBUG("dce_alloc IH264VDEC_Status successful status=%p", status);
969
970 status->data.buf = (XDAS_Int8 *) version_buffer;
971 h264_status = (IH264VDEC_Status *) status;
972 DEBUG("dce_alloc IH264VDEC_Status successful h264_status=%p", h264_status);
973
974 //((IH264VDEC_Status*)h264_status)->viddec3Status->data.buf = version_buffer;
975 err = VIDDEC3_control(codec, XDM_GETVERSION, (VIDDEC3_DynamicParams *) h264_dynParams, (VIDDEC3_Status *) h264_status);
976
977 DEBUG("dce_alloc IH264VDEC_Status get_version h264_status=%s", (((VIDDEC3_Status *)h264_status)->data.buf));
978 break;
979 default :
980 DEBUG("Not implemented or supported codec_switch %d", codec_switch);
981 }
982
983 if( status ) {
984 dce_free(status);
985 }
986#endif
987
988 switch( codec_switch ) {
989 case DCE_TEST_H264 :
990
991 DEBUG("dce_alloc IH264VDEC_DynamicParams successful dynParams=%p", dynParams);
992 h264_dynParams = (IH264VDEC_DynamicParams *) dynParams;
993 DEBUG("dce_alloc IH264VDEC_DynamicParams successful h264_dynParams=%p", h264_dynParams);
994
995 status = dce_alloc(sizeof(IH264VDEC_Status));
996 status->size = sizeof(IH264VDEC_Status);
997 DEBUG("dce_alloc IH264VDEC_Status successful status=%p", status);
998
999 h264_status = (IH264VDEC_Status *) status;
1000 DEBUG("dce_alloc IH264VDEC_Status successful h264_status=%p", h264_status);
1001 err = VIDDEC3_control(codec, XDM_SETPARAMS, (VIDDEC3_DynamicParams *) h264_dynParams, (VIDDEC3_Status *) h264_status);
1002 break;
1003
1004 case DCE_TEST_MPEG4 :
1005
1006 DEBUG("dce_alloc IMPEG4VDEC_DynamicParams successful dynParams=%p", dynParams);
1007 mpeg4_dynParams = (IMPEG4VDEC_DynamicParams *) dynParams;
1008 DEBUG("dce_alloc IMPEG4VDEC_DynamicParams successful mpeg4_dynParams=%p", mpeg4_dynParams);
1009
1010 status = dce_alloc(sizeof(IMPEG4VDEC_Status));
1011 status->size = sizeof(IMPEG4VDEC_Status);
1012 DEBUG("dce_alloc IMPEG4VDEC_Status successful status=%p", status);
1013
1014 mpeg4_status = (IMPEG4VDEC_Status *) status;
1015 DEBUG("dce_alloc IMPEG4VDEC_Status successful mpeg4_status=%p", mpeg4_status);
1016 err = VIDDEC3_control(codec, XDM_SETPARAMS, (VIDDEC3_DynamicParams *) mpeg4_dynParams, (VIDDEC3_Status *) mpeg4_status);
1017 break;
1018
1019 case DCE_TEST_VC1SMP :
1020 case DCE_TEST_VC1AP :
1021
1022 DEBUG("dce_alloc IVC1VDEC_DynamicParams successful dynParams=%p", dynParams);
1023 vc1_dynParams = (IVC1VDEC_DynamicParams *) dynParams;
1024 DEBUG("dce_alloc IVC1VDEC_DynamicParams successful vc1_dynParams=%p", vc1_dynParams);
1025
1026 status = dce_alloc(sizeof(IVC1VDEC_Status));
1027 status->size = sizeof(IVC1VDEC_Status);
1028 DEBUG("dce_alloc IVC1VDEC_Status successful status=%p", status);
1029
1030 vc1_status = (IVC1VDEC_Status *) status;
1031 DEBUG("dce_alloc IVC1VDEC_Status successful vc1_status=%p", vc1_status);
1032 err = VIDDEC3_control(codec, XDM_SETPARAMS, (VIDDEC3_DynamicParams *) vc1_dynParams, (VIDDEC3_Status *) vc1_status);
1033 break;
1034
1035 case DCE_TEST_MJPEG :
1036
1037 DEBUG("dce_alloc IJPEGVDEC_DynamicParams successful dynParams=%p", dynParams);
1038 mjpeg_dynParams = (IJPEGVDEC_DynamicParams *) dynParams;
1039 mjpeg_dynParams->decodeThumbnail = 0;
1040 mjpeg_dynParams->thumbnailMode = IJPEGVDEC_THUMBNAIL_DOWNSAMPLE;
1041 mjpeg_dynParams->downsamplingFactor = IJPEGVDEC_NODOWNSAMPLE;
1042 mjpeg_dynParams->streamingCompliant = 1;
1043
1044 DEBUG("dce_alloc IJPEGVDEC_DynamicParams successful mjpeg_dynParams=%p", mjpeg_dynParams);
1045
1046 status = dce_alloc(sizeof(IVC1VDEC_Status));
1047 status->size = sizeof(IJPEGVDEC_Status);
1048 DEBUG("dce_alloc IVC1VDEC_Status successful status=%p", status);
1049
1050 mjpeg_status = (IJPEGVDEC_Status *) status;
1051 DEBUG("dce_alloc IJPEGVDEC_Status successful mjpeg_status=%p", mjpeg_status);
1052 err = VIDDEC3_control(codec, XDM_SETPARAMS, (VIDDEC3_DynamicParams *) mjpeg_dynParams, (VIDDEC3_Status *) mjpeg_status);
1053 break;
1054#ifdef ENABLE_MPEG2
1055 case DCE_TEST_MPEG2 :
1056
1057 DEBUG("dce_alloc IMPEG2VDEC_DynamicParams successful dynParams=%p", dynParams);
1058 mpeg2_dynParams = (IMPEG2VDEC_DynamicParams *) dynParams;
1059 //MPEG2 buffer width should be 128 byte aligned for non TILER (atleast)
1060 //If displayWidth=0 then MPEG2 codec does not have a way to calculate
1061 //the stride as compared to other codecs which can calculate it from
1062 //buffer size and image height.stride=buffersize/(height*1.5)
1063 mpeg2_dynParams->viddecDynamicParams.displayWidth = padded_width;
1064
1065 DEBUG("dce_alloc IMPEG2VDEC_DynamicParams successful mpeg2_dynParams=%p", mpeg2_dynParams);
1066
1067 status = dce_alloc(sizeof(IMPEG2VDEC_Status));
1068 status->size = sizeof(IMPEG2VDEC_Status);
1069 DEBUG("dce_alloc IMPEG2VDEC_Status successful status=%p", status);
1070
1071 mpeg2_status = (IMPEG2VDEC_Status *) status;
1072 DEBUG("dce_alloc IMPEG2VDEC_Status successful mpeg2_status=%p", mpeg2_status);
1073 err = VIDDEC3_control(codec, XDM_SETPARAMS, (VIDDEC3_DynamicParams *) mpeg2_dynParams, (VIDDEC3_Status *) mpeg2_status);
1074 break;
1075#endif
1076 default :
1077 DEBUG("Not implemented or supported codec_switch %d", codec_switch);
1078 }
1079
1080 if( err ) {
1081 ERROR("fail: %d", err);
1082 goto shutdown;
1083 }
1084
1085 DEBUG("VIDDEC3_control XDM_SETPARAMS successful");
1086
1087 DEBUG("input buffer configuration width %d height %d", width, height);
1088 inBufs = dce_alloc(sizeof(XDM2_BufDesc));
1089 inBufs->numBufs = 1;
1090 input = tiler_alloc(width * height, 0);
1091 inBufs->descs[0].buf = (XDAS_Int8 *)input;
1092 inBufs->descs[0].memType = XDM_MEMTYPE_RAW;
1093
1094 DEBUG("inBufs->descs[0].buf %p input %p", inBufs->descs[0].buf, input);
1095
1096 outBufs = dce_alloc(sizeof(XDM2_BufDesc));
1097
1098 DEBUG("output buffer configuration num_buffers %d padded_width %d padded_height %d", num_buffers, padded_width, padded_height);
1099
1100#ifdef PROFILE_TIME
1101 uint64_t alloc_time_start = mark_microsecond(NULL);
1102#endif
1103
1104 if( !(strcmp(tilerbuffer, "tiler"))) {
1105 DEBUG("Output allocate through tiler");
1106 tiler = 1;
1107 err = output_allocate(outBufs, num_buffers,
1108 padded_width, padded_height, stride);
1109 } else {
1110 DEBUG("Output allocate through non-tiler");
1111 tiler = 0;
1112 err = output_allocate_nonTiler(outBufs, num_buffers,
1113 padded_width, padded_height, stride);
1114 }
1115
1116#ifdef PROFILE_TIME
1117 output_alloc_time = mark_microsecond(&alloc_time_start);
1118#endif
1119
1120 if( err ) {
1121 ERROR("fail: %d", err);
1122 goto shutdown;
1123 }
1124
1125 inArgs = dce_alloc(sizeof(IVIDDEC3_InArgs));
1126 inArgs->size = sizeof(IVIDDEC3_InArgs);
1127
1128 outArgs = dce_alloc(sizeof(IVIDDEC3_OutArgs));
1129 outArgs->size = sizeof(IVIDDEC3_OutArgs);
1130
1131#ifdef PROFILE_TIME
1132 total_init_time = (uint64_t)mark_microsecond(&init_start_time);
1133 INFO("total_init_time %llu output_alloc_time %llu actual init time in: %lld us", total_init_time, output_alloc_time, total_init_time - output_alloc_time);
1134#endif
1135
1136 while( inBufs->numBufs && outBufs->numBufs ) {
1137 OutputBuffer *buf;
1138 int n, i;
1139
1140 if( !outBufsInUse ) {
1141 buf = output_get();
1142 if( !buf ) {
1143 ERROR("fail: out of buffers");
1144 goto shutdown;
1145 }
1146 } else {
1147 buf = 0;
1148 }
1149
1150 n = read_input(in_pattern, in_cnt, input);
1151 if( n && (n != -1)) {
1152 eof = 0;
1153 inBufs->numBufs = 1;
1154 inBufs->descs[0].buf = (XDAS_Int8 *)input;
1155 inBufs->descs[0].bufSize.bytes = n;
1156 inArgs->numBytes = n;
1157 DEBUG("push: %d (%d bytes) (%p)", in_cnt, n, buf);
1158 in_cnt++;
1159
1160 /*
1161 * Input buffer has data to be decoded.
1162 */
1163 inArgs->inputID = (XDAS_Int32)buf;
1164 if( !outBufsInUse ) {
1165 outBufs->numBufs = 2;
1166 outBufs->descs[0].buf = (XDAS_Int8 *)buf->y;
1167 outBufs->descs[1].buf = (XDAS_Int8 *)buf->uv;
1168 }
1169 } else if( n == -1 ) {
1170
1171 // Set EOF as 1 to ensure flush completes
1172 eof = 1;
1173 in_cnt++;
1174
1175 switch( codec_switch ) {
1176 case DCE_TEST_H264 :
1177 DEBUG("Calling VIDDEC3_control XDM_FLUSH h264_dynParams %p h264_status %p", h264_dynParams, h264_status);
1178 err = VIDDEC3_control(codec, XDM_FLUSH, (VIDDEC3_DynamicParams *) h264_dynParams, (VIDDEC3_Status *) h264_status);
1179 break;
1180 case DCE_TEST_MPEG4 :
1181 DEBUG("Calling VIDDEC3_control XDM_FLUSH mpeg4_dynParams %p mpeg4_status %p", mpeg4_dynParams, mpeg4_status);
1182 err = VIDDEC3_control(codec, XDM_FLUSH, (VIDDEC3_DynamicParams *) mpeg4_dynParams, (VIDDEC3_Status *) mpeg4_status);
1183 break;
1184 case DCE_TEST_VC1SMP :
1185 case DCE_TEST_VC1AP :
1186 DEBUG("Calling VIDDEC3_control XDM_FLUSH vc1_dynParams %p vc1_status %p", vc1_dynParams, vc1_status);
1187 err = VIDDEC3_control(codec, XDM_FLUSH, (VIDDEC3_DynamicParams *) vc1_dynParams, (VIDDEC3_Status *) vc1_status);
1188 break;
1189 case DCE_TEST_MJPEG :
1190 DEBUG("Calling VIDDEC3_control XDM_FLUSH mjpeg_dynParams %p mjpeg_status %p", mjpeg_dynParams, mjpeg_status);
1191 err = VIDDEC3_control(codec, XDM_FLUSH, (VIDDEC3_DynamicParams *) mjpeg_dynParams, (VIDDEC3_Status *) mjpeg_status);
1192 break;
1193#ifdef ENABLE_MPEG2
1194 case DCE_TEST_MPEG2 :
1195 DEBUG("Calling VIDDEC3_control XDM_FLUSH mpeg2_dynParams %p mpeg2_status %p", mpeg2_dynParams, mpeg2_status);
1196 err = VIDDEC3_control(codec, XDM_FLUSH, (VIDDEC3_DynamicParams *) mpeg2_dynParams, (VIDDEC3_Status *) mpeg2_status);
1197 break;
1198#endif
1199 }
1200
1201 /* We have sent the XDM_FLUSH, call VIDDEC3_process until we get
1202 * an error of XDM_EFAIL which tells us there are no more buffers
1203 * at codec level.
1204 */
1205
1206 inArgs->inputID = 0;
1207 inArgs->numBytes = 0;
1208 inBufs->descs[0].buf = NULL;
1209 inBufs->descs[0].bufSize.bytes = 0;
1210 outBufs->numBufs = 0;
1211 outBufs->descs[0].buf = NULL;
1212 outBufs->descs[1].buf = NULL;
1213 if( buf ) {
1214 output_release(buf);
1215 }
1216 outBufsInUse = 0;
1217
1218
1219 } else {
1220 /* end of input.. */
1221 inBufs->numBufs = 0;
1222 eof = 1;
1223
1224 switch( codec_switch ) {
1225 case DCE_TEST_H264 :
1226 DEBUG("Calling VIDDEC3_control XDM_FLUSH h264_dynParams %p h264_status %p", h264_dynParams, h264_status);
1227 err = VIDDEC3_control(codec, XDM_FLUSH, (VIDDEC3_DynamicParams *) h264_dynParams, (VIDDEC3_Status *) h264_status);
1228 break;
1229 case DCE_TEST_MPEG4 :
1230 DEBUG("Calling VIDDEC3_control XDM_FLUSH mpeg4_dynParams %p mpeg4_status %p", mpeg4_dynParams, mpeg4_status);
1231 err = VIDDEC3_control(codec, XDM_FLUSH, (VIDDEC3_DynamicParams *) mpeg4_dynParams, (VIDDEC3_Status *) mpeg4_status);
1232 break;
1233 case DCE_TEST_VC1SMP :
1234 case DCE_TEST_VC1AP :
1235 DEBUG("Calling VIDDEC3_control XDM_FLUSH vc1_dynParams %p vc1_status %p", vc1_dynParams, vc1_status);
1236 err = VIDDEC3_control(codec, XDM_FLUSH, (VIDDEC3_DynamicParams *) vc1_dynParams, (VIDDEC3_Status *) vc1_status);
1237 break;
1238 case DCE_TEST_MJPEG :
1239 DEBUG("Calling VIDDEC3_control XDM_FLUSH mjpeg_dynParams %p mjpeg_status %p", mjpeg_dynParams, mjpeg_status);
1240 err = VIDDEC3_control(codec, XDM_FLUSH, (VIDDEC3_DynamicParams *) mjpeg_dynParams, (VIDDEC3_Status *) mjpeg_status);
1241 break;
1242#ifdef ENABLE_MPEG2
1243 case DCE_TEST_MPEG2 :
1244 DEBUG("Calling VIDDEC3_control XDM_FLUSH mpeg2_dynParams %p mpeg2_status %p", mpeg2_dynParams, mpeg2_status);
1245 err = VIDDEC3_control(codec, XDM_FLUSH, (VIDDEC3_DynamicParams *) mpeg2_dynParams, (VIDDEC3_Status *) mpeg2_status);
1246 break;
1247#endif
1248 }
1249
1250 /* We have sent the XDM_FLUSH, call VIDDEC3_process until we get
1251 * an error of XDM_EFAIL which tells us there are no more buffers
1252 * at codec level.
1253 */
1254
1255 inArgs->inputID = 0;
1256 inArgs->numBytes = 0;
1257 inBufs->numBufs = 0;
1258 inBufs->descs[0].buf = NULL;
1259 inBufs->descs[0].bufSize.bytes = 0;
1260 outBufs->numBufs = 0;
1261 outBufs->descs[0].buf = NULL;
1262 outBufs->descs[1].buf = NULL;
1263 if( buf ) {
1264 output_release(buf);
1265 }
1266 }
1267
1268#ifdef DUMPINPUTDATA
1269 DEBUG("input data dump inArgs->numBytes[%d] inputDump[%p]", inArgs->numBytes, inputDump);
1270
1271 //Dump the file
1272 if( inputDump == NULL ) {
1273 inputDump = fopen("/tmp/inputdump.h264", "ab");
1274 DEBUG("input data dump file open %p errno %d", inputDump, errno);
1275 if( inputDump == NULL ) {
1276 DEBUG("Opening input Dump /tmp/inputdump.h264 file FAILED");
1277 }
1278 }
1279 DEBUG("input data dump file open %p Successful", inputDump);
1280
1281 fwrite(input, sizeof(char), inArgs->numBytes, inputDump);
1282 DEBUG("Dumping input file with size = %d ", inArgs->numBytes);
1283 fflush(inputDump);
1284 fclose(inputDump);
1285 inputDump = NULL;
1286 #endif
1287
1288 int iters = 0;
1289
1290 do {
1291 DEBUG("Calling VIDDEC3_process inArgs->inputID=%x inBufs->descs[0].buf %p inBufs->descs.bufSize %d input %p",
1292 inArgs->inputID, inBufs->descs[0].buf, (int) inBufs->descs[0].bufSize.bytes, input);
1293#ifdef PROFILE_TIME
1294 codec_process_time = mark_microsecond(NULL);
1295#endif
1296 err = VIDDEC3_process(codec, inBufs, outBufs, inArgs, outArgs);
1297#ifdef PROFILE_TIME
1298 INFO("processed returned in: %llu us", (uint64_t) mark_microsecond(&codec_process_time));
1299#endif
1300 if( err ) {
1301 if( XDM_ISFATALERROR(outArgs->extendedError)) {
1302 ERROR("process returned error: %d\n", err);
1303 ERROR("extendedError: %08x", outArgs->extendedError);
1304 goto shutdown;
1305 } else if( eof ) {
1306 /*
1307 * Flush has been ordered, processing the returned output from codec.
1308 * For H.264, bit 18 - IH264VDEC_ERR_STREAM_END indicates flush is completed.
1309 * For MPEG4, bit 24 - IMPEG4VDEC_ERR_STREAM_END indicates flush is completed.
1310 * Only return XDM_EFAIL, when those bit are set.
1311 */
1312 ERROR("Codec_process returned err=%d, extendedError=%08x", err, outArgs->extendedError);
1313 err = XDM_EFAIL;
1314
1315 if((!(((outArgs->extendedError) >> 24) & 0x1)) &&
1316 ((ivahd_decode_type == 2 /*IVAHD_MP4V_DECODE*/) ||
1317 (ivahd_decode_type == 3 /*IVAHD_S263_DECODE*/))) {
1318 err = XDM_EOK;
1319 }
1320
1321 if((!(((outArgs->extendedError) >> 18) & 0x1)) &&
1322 ((ivahd_decode_type == 1 /*IVAHD_H264_DECODE*/) ||
1323 (ivahd_decode_type == 0 /*IVAHD_AVC1_DECODE*/))) {
1324 err = XDM_EOK;
1325 }
1326
1327 if( err == XDM_EFAIL ) {
1328 DEBUG("-------------------- Flush completed------------------------");
1329 }
1330 } else {
1331 DEBUG("Non-fatal err=%d, extendedError=%08x", err, outArgs->extendedError);
1332 err = XDM_EOK;
1333 }
1334 }
1335
1336 /*
1337 * Handling of output data from codec
1338 */
1339 if( tiler ) {
1340 for( i = 0; outArgs->outputID[i]; i++ ) {
1341 /* calculate offset to region of interest */
1342 XDM_Rect *r = &(outArgs->displayBufs.bufDesc[0].activeFrameRegion);
1343
1344 int yoff = (r->topLeft.y * stride) + r->topLeft.x;
1345 int uvoff = (r->topLeft.y * stride / 2) + (stride * padded_height) + r->topLeft.x;
1346
1347 /* get the output buffer and write it to file */
1348 buf = (OutputBuffer *)outArgs->outputID[i];
1349 DEBUG("pop: %d (%p)", out_cnt, buf);
1350
1351 if( out_cnt < 30 ) { // write first 30 frames to output file out_cnt < 300
1352 write_output(out_pattern, out_cnt++, buf->buf + yoff,
1353 buf->buf + uvoff, stride);
1354 } else {
1355 out_cnt++;
1356 }
1357 }
1358 } else {
1359 for( i = 0; outArgs->outputID[i]; i++ ) {
1360 /* calculate offset to region of interest */
1361 XDM_Rect *r = &(outArgs->displayBufs.bufDesc[0].activeFrameRegion);
1362
1363 int yoff = (r->topLeft.y * padded_width) + r->topLeft.x;
1364 int uvoff = (r->topLeft.y * padded_width / 2) + (padded_height * padded_width) + r->topLeft.x;
1365
1366 /* get the output buffer and write it to file */
1367 buf = (OutputBuffer *)outArgs->outputID[i];
1368 DEBUG("pop: %d (%p)", out_cnt, buf);
1369
1370 if( out_cnt < 300 ) { // write first 300 frames to output file
1371 write_output(out_pattern, out_cnt++, buf->buf + yoff,
1372 buf->buf + uvoff, padded_width);
1373 } else {
1374 out_cnt++;
1375 }
1376 }
1377 }
1378
1379 for( i = 0; outArgs->freeBufID[i]; i++ ) {
1380 DEBUG("freeBufID[%d] = %d", i, outArgs->freeBufID[i]);
1381 buf = (OutputBuffer *)outArgs->freeBufID[i];
1382 output_release(buf);
1383 }
1384
1385 if( outArgs->outBufsInUseFlag ) {
1386 outBufsInUse = TRUE;
1387 DEBUG("outBufsInUseFlag is SET. Not sending a new output buffer to codec on the next Codec_process ");
1388 } else {
1389 outBufsInUse = FALSE;
1390 }
1391
1392 ++iters; // Guard for infinite VIDDEC3_PROCESS loop when codec never return XDM_EFAIL
1393 } while( eof && (err != XDM_EFAIL) && (iters < 100)); // Multiple VIDDEC3_process when eof until err == XDM_EFAIL
1394
1395 }
1396
1397shutdown:
1398
1399 printf("\nDeleting codec...\n");
1400 VIDDEC3_delete(codec);
1401
1402out:
1403 if( engine ) {
1404 Engine_close(engine);
1405 }
1406 if( params ) {
1407 dce_free(params);
1408 }
1409 if( dynParams ) {
1410 dce_free(dynParams);
1411 }
1412 if( status ) {
1413 dce_free(status);
1414 }
1415 if( inBufs ) {
1416 dce_free(inBufs);
1417 }
1418 if( outBufs ) {
1419 dce_free(outBufs);
1420 }
1421 if( inArgs ) {
1422 dce_free(inArgs);
1423 }
1424 if( outArgs ) {
1425 dce_free(outArgs);
1426 }
1427 if( input ) {
1428 MemMgr_Free(input);
1429 }
1430
1431 output_free();
1432
1433 printf("DCE test completed...\n");
1434
1435 return (0);
1436}
1437
diff --git a/test_qnx/dce_test.use b/test_qnx/dce_test.use
new file mode 100644
index 0000000..413d849
--- /dev/null
+++ b/test_qnx/dce_test.use
@@ -0,0 +1,38 @@
1/*
2 * $QNXLicenseC:
3 */
4
5
6%C dce test application to test libdce
7
8Syntax:
9%C [options]
10Options:
11 -h Print out the help information
12
13Examples:
141. decoding h.264
15 dce_test width height framesize inpattern outpattern codec tiler/nontiler
16 dce_test 320 240 framesize.txt inputfile.h264 outputfile.yuv h264 tiler
17
182. decoding mpeg4
19 dce_test width height framesize inpattern outpattern codec tiler/nontiler
20 dce_test 640 480 framesize.txt inputfile.m4v outputfile.yuv mpeg4 nontiler
21
223. decoding vc1ap
23 dce_test width height framesize inpattern outpattern codec tiler/nontiler
24 dce_test 720 480 framesize.txt inputfile.vc1 outputfile.yuv vc1ap tiler
25
264. decoding vc1smp
27 dce_test width height framesize inpattern outpattern codec tiler/nontiler
28 dce_test 320 240 framesize.txt inputfile.vc1 outputfile.yuv vc1smp nontiler
29
305. decoding mjpeg
31 dce_test width height framesize inpattern outpattern codec tiler/nontiler
32 dce_test 1280 720 framesize.txt inputfile.bin outputfile.yuv mjpeg tiler
33
346. decoding mpeg2
35 dce_test width height framesize inpattern outpattern codec tiler/nontiler
36 dce_test 1920 1088 framesize.txt inputfile.bin outputfile.yuv mpeg2 nontiler
37
38Currently supported codecs: h264, mpeg4, vc1ap, vc1smp, mjpeg, mpeg2