summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaurabh Bipin Chandra2013-04-22 11:42:19 -0500
committerSaurabh Bipin Chandra2013-04-26 09:14:28 -0500
commit6647d1f16d70b9d867ce5b7aef92705939aa5975 (patch)
tree73b154f99e7ceff809c8a98be6489e4ee11d0877
downloadrepo-libdce-6647d1f16d70b9d867ce5b7aef92705939aa5975.tar.gz
repo-libdce-6647d1f16d70b9d867ce5b7aef92705939aa5975.tar.xz
repo-libdce-6647d1f16d70b9d867ce5b7aef92705939aa5975.zip
[libDCE] Add IPC 3.x Adapted code to Repository3.00.01.00
This patch adds libdce code to the repository. LibDCE has been adapted to use the MmRpc layer of IPC 3.x. This version of LibDCE is expected to work on QNX. Patchset 2 adds/modifies: 1. Removes Tiler 2D allocation/free for now. 2. Corrects memplugin_free() for Tiler 1D. 3. Modifies dce_test app to dump output till 30 frames. 4. Renamed dce.h to libdce.h. 5. Corrected header files across all files. 6. Build configuration for QNX 7. Removes build warnings. 8. Add README for Build instructions 9. Takes care of comments of Buddy and Pradeep. Patchset 3 adds/modifies: 1. Reduced Stack usage of each function. 2. Add ptr check in memplugin and remove from libdce. 3. Add DCE_Assert macros. 4. Add DCE_error_status enum. 5. Comments Cleanup 6. Make some functions static. 7. process() cleanup including removing reply_buf. 8. Add else if (for codec_type == Encoder type) 9. Converted Macros to Inline functions. 10.Converted init and deinit to dce_init and dce_deinit functions. 11. Removed dce_init() and dce_deinit() declarations Patchset 4 adds/modifies: 1. Assert Input function arguments. 2. Correct copyright year. 3. Correct memplugin_free for Shared memory. 4. Create dce_priv.h and move trace and assert macros to the header. 5. Redeclare mem_type enum and add mem_error_status enum in memplugin.h and make corresponding changes. 6. Add asserts in memplugin. Intention of some of the changes above is to move towards delinking Libdce and Memplugin. Patchset 5: 1. Missed to add dce_priv.h file. Patchset 6: 1. Take care Pradeep's comment. Change-Id: I6e5e37b7088362e7bad66200fc3454bb828e0eff Signed-off-by: Saurabh Bipin Chandra <a0131926@ti.com>
-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