diff options
Diffstat (limited to 'libdce.c')
-rw-r--r-- | libdce.c | 711 |
1 files changed, 711 insertions, 0 deletions
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 | ||
93 | int dce_auth_x11(int *fd); | ||
94 | #endif /* GLP_X11 */ | ||
95 | #ifdef GLP_WAYLAND | ||
96 | int dce_auth_wayland(int *fd); | ||
97 | #endif /* GLP_WAYLAND */ | ||
98 | |||
99 | static int fd = -1; | ||
100 | static struct omap_device *dev; | ||
101 | static int ioctl_base; | ||
102 | #define CMD(name) (ioctl_base + DRM_OMAP_DCE_##name) | ||
103 | |||
104 | uint32_t dce_debug = 3; | ||
105 | #endif /* BUILDOS_GLP */ | ||
106 | |||
107 | |||
108 | /********************* GLOBALS ***********************/ | ||
109 | /* Hande used for Remote Communication */ | ||
110 | static MmRpc_Handle MmRpcHandle = NULL; | ||
111 | static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; | ||
112 | static int count = 0; | ||
113 | |||
114 | |||
115 | /****************** INLINE FUNCTIONS ********************/ | ||
116 | |||
117 | static 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 | |||
125 | static 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 | |||
133 | static 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 | |||
140 | static 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 */ | ||
154 | void *dce_alloc(int sz) | ||
155 | { | ||
156 | return (memplugin_alloc(sz, 0, TILER_1D_BUFFER)); | ||
157 | } | ||
158 | |||
159 | void dce_free(void *ptr) | ||
160 | { | ||
161 | memplugin_free(ptr, TILER_1D_BUFFER); | ||
162 | } | ||
163 | |||
164 | /*************** Startup/Shutdown Functions ***********************/ | ||
165 | static 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); | ||
186 | EXIT: | ||
187 | pthread_mutex_unlock(&mutex); | ||
188 | return (eError); | ||
189 | } | ||
190 | |||
191 | static 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; | ||
204 | EXIT: | ||
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 | */ | ||
218 | Engine_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 | |||
258 | EXIT: | ||
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 | */ | ||
269 | Void 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 | |||
295 | EXIT: | ||
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 | */ | ||
316 | static 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 | |||
358 | EXIT: | ||
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 | */ | ||
379 | static 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 | |||
418 | EXIT: | ||
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 | */ | ||
441 | static 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 | |||
485 | EXIT: | ||
486 | memplugin_free(codec_get_version_msg, TILER_1D_BUFFER); | ||
487 | |||
488 | return (eError); | ||
489 | } | ||
490 | |||
491 | typedef 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 | */ | ||
515 | static 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); | ||
576 | EXIT: | ||
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 | */ | ||
587 | static 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 | |||
614 | EXIT: | ||
615 | memplugin_free(codec_delete_msg, TILER_1D_BUFFER); | ||
616 | |||
617 | return; | ||
618 | } | ||
619 | |||
620 | /*************** Deocder Codec Engine Functions ***********************/ | ||
621 | VIDDEC3_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 | |||
632 | XDAS_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 | |||
648 | XDAS_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 | |||
661 | Void 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 ***********************/ | ||
669 | VIDENC2_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 | |||
680 | XDAS_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 | |||
692 | XDAS_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 | |||
705 | Void VIDENC2_delete(VIDENC2_Handle codec) | ||
706 | { | ||
707 | DEBUG(">> codec=%p", codec); | ||
708 | delete(codec, OMAP_DCE_VIDENC2); | ||
709 | DEBUG("<<"); | ||
710 | } | ||
711 | |||