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 */
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 */
66 #include <stdlib.h>
67 #include <string.h>
68 #include <stdio.h>
69 #include <pthread.h>
70 #include <errno.h>
72 #include <xdc/std.h>
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 */
81 /* IPC Headers */
82 #include <MmRpc.h>
84 /*DCE Headers */
85 #include "libdce.h"
86 #include "dce_rpc.h"
87 #include "dce_priv.h"
88 #include "memplugin.h"
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 */
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)
104 uint32_t dce_debug = 3;
105 #endif /* BUILDOS_GLP */
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;
115 /****************** INLINE FUNCTIONS ********************/
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 }
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 }
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 }
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 }
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 }
159 void dce_free(void *ptr)
160 {
161 memplugin_free(ptr, TILER_1D_BUFFER);
162 }
164 /*************** Startup/Shutdown Functions ***********************/
165 static int dce_init(void)
166 {
167 dce_error_status eError = DCE_EOK;
168 MmRpc_Params args;
170 printf(" >> dce_init\n");
172 pthread_mutex_lock(&mutex);
174 count++;
175 /* Check if already Initialized */
176 _ASSERT(count == 1, DCE_EOK);
178 /* Create remote server insance */
179 MmRpc_Params_init(&args);
181 eError = MmRpc_create(DCE_DEVICE_NAME, &args, &MmRpcHandle);
183 _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CREATE_FAIL, count--);
185 printf("open(/dev/" DCE_DEVICE_NAME ") -> 0x%x\n", (int)MmRpcHandle);
186 EXIT:
187 pthread_mutex_unlock(&mutex);
188 return (eError);
189 }
191 static void dce_deinit(void)
192 {
193 pthread_mutex_lock(&mutex);
195 count--;
196 if( count > 0 ) {
197 goto EXIT;
198 }
200 if( MmRpcHandle != NULL ) {
201 MmRpc_delete(&MmRpcHandle);
202 }
203 MmRpcHandle = NULL;
204 EXIT:
205 pthread_mutex_unlock(&mutex);
206 return;
207 }
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;
226 _ASSERT(name != '\0', DCE_EINVALID_INPUT);
228 /* Initialize DCE and IPC. In case of Error Deinitialize them */
229 _ASSERT_AND_EXECUTE(dce_init() == DCE_EOK, DCE_EIPC_CREATE_FAIL, dce_deinit());
231 printf(">> Engine_open Params::name = %s size = %d\n", name, strlen(name));
232 /* Allocate Shared memory for the engine_open rpc msg structure*/
233 /* Tiler Memory preferred for now for First level testing */
234 engine_open_msg = memplugin_alloc(sizeof(dce_engine_open), 0, TILER_1D_BUFFER);
236 _ASSERT_AND_EXECUTE(engine_open_msg != NULL, DCE_EOUT_OF_MEMORY, eng_handle = NULL);
238 /* Populating the msg structure with all the params */
239 /* Populating all params into a struct avoid individual address translations of name, ec */
240 strncpy(engine_open_msg->name, name, strlen(name));
241 engine_open_msg->eng_handle = NULL;
243 /* Marshall function arguments into the send buffer */
244 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_ENGINE_OPEN, 1, 0, NULL);
245 Fill_MmRpc_fxnCtx_Ptr_Params(fxnCtx.params, sizeof(dce_engine_open), engine_open_msg, NULL);
247 /* Invoke the Remote function through MmRpc */
248 eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
250 /* In case of Error, the Application will get a NULL Engine Handle */
251 _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CALL_FAIL, eng_handle = NULL);
253 /* Populate return arguments */
254 eng_handle = engine_open_msg->eng_handle;
255 ec[0] = engine_open_msg->error_code;
257 EXIT:
258 memplugin_free(engine_open_msg, TILER_1D_BUFFER);
260 return (eng_handle);
261 }
263 /*===============================================================*/
264 /** Engine_close : Close Engine.
265 *
266 * @ param engine [in] : Engine Handle obtained in Engine_open() call.
267 */
268 Void Engine_close(Engine_Handle engine)
269 {
270 MmRpc_FxnCtx fxnCtx;
271 int32_t fxnRet;
272 dce_error_status eError = DCE_EOK;
273 dce_engine_close *engine_close_msg = NULL;
275 _ASSERT(engine != NULL, DCE_EINVALID_INPUT);
277 /* Allocate Shared/Tiler memory for the engine_close rpc msg structure*/
278 engine_close_msg = memplugin_alloc(sizeof(dce_engine_close), 0, TILER_1D_BUFFER);
280 _ASSERT(engine_close_msg != NULL, DCE_EOUT_OF_MEMORY);
282 /* Populating the msg structure with all the params */
283 engine_close_msg->eng_handle = engine;
285 /* Marshall function arguments into the send buffer */
286 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_ENGINE_CLOSE, 1, 0, NULL);
287 Fill_MmRpc_fxnCtx_Ptr_Params(fxnCtx.params, sizeof(dce_engine_close), engine_close_msg, NULL);
289 /* Invoke the Remote function through MmRpc */
290 eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
292 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
294 EXIT:
295 memplugin_free(engine_close_msg, TILER_1D_BUFFER);
297 dce_deinit();
298 return;
299 }
301 /*===============================================================*/
302 /** Functions create(), control(), get_version(), process(), delete() are common codec
303 * glue function signatures which are same for both encoder and decoder
304 */
305 /*===============================================================*/
306 /** create : Create Encoder/Decoder codec.
307 *
308 * @ param engine [in] : Engine Handle obtained in Engine_open() call.
309 * @ param name [in] : Name of Encoder or Decoder codec.
310 * @ param params [in] : Static parameters of codec.
311 * @ param codec_id [in] : To differentiate between Encoder and Decoder codecs.
312 * @ return : Codec Handle is returned to be used for control, process, delete calls.
313 * In case of error, NULL is returned.
314 */
315 static void *create(Engine_Handle engine, String name, void *params, dce_codec_type codec_id)
316 {
317 MmRpc_FxnCtx fxnCtx;
318 MmRpc_Xlt xltAry;
319 int32_t fxnRet;
320 dce_error_status eError = DCE_EOK;
321 dce_codec_create *codec_create_msg = NULL;
322 void *codec_handle = NULL;
324 _ASSERT(name != '\0', DCE_EINVALID_INPUT);
325 _ASSERT(engine != NULL, DCE_EINVALID_INPUT);
326 _ASSERT(params != NULL, DCE_EINVALID_INPUT);
328 /* Allocate Shared/Tiler memory for the codec_create rpc msg structure*/
329 codec_create_msg = memplugin_alloc(sizeof(dce_codec_create), 0, TILER_1D_BUFFER);
331 _ASSERT_AND_EXECUTE(codec_create_msg != NULL, DCE_EOUT_OF_MEMORY, codec_handle = NULL);
333 /* Populating the msg structure with all the params */
334 codec_create_msg->engine = engine;
335 strncpy(codec_create_msg->codec_name, name, strlen(name));
336 codec_create_msg->codec_id = codec_id;
337 codec_create_msg->codec_handle = NULL;
338 codec_create_msg->static_params = params;
340 /* Marshall function arguments into the send buffer */
341 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_CREATE, 1, 1, &xltAry);
342 Fill_MmRpc_fxnCtx_Ptr_Params(&(fxnCtx.params[0]), sizeof(dce_codec_create), codec_create_msg, NULL);
344 /* Mention the virtual pointers that need translation */
345 /* Allocations through dce_alloc need translation */
346 /* In this case the static params buffer need translation */
347 Fill_MmRpc_fxnCtx_Xlt_Array(fxnCtx.xltAry, 0, (int32_t)codec_create_msg, (int32_t)&(codec_create_msg->static_params), NULL);
349 /* Invoke the Remote function through MmRpc */
350 eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
352 /* In case of Error, the Application will get a NULL Codec Handle */
353 _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CALL_FAIL, codec_handle = NULL);
355 codec_handle = codec_create_msg->codec_handle;
357 EXIT:
358 memplugin_free(codec_create_msg, TILER_1D_BUFFER);
360 return (codec_handle);
361 }
363 /*===============================================================*/
364 /** control : Codec control call.
365 *
366 * @ param codec [in] : Codec Handle obtained in create() call.
367 * @ param id [in] : Command id for XDM control operation.
368 * @ param dynParams [in] : Dynamic input parameters to Codec.
369 * @ param status [out] : Codec returned status parameters.
370 * @ param codec_id [in] : To differentiate between Encoder and Decoder codecs.
371 * @ return : Status of control() call is returned.
372 * #XDM_EOK [0] : Success.
373 * #XDM_EFAIL [-1] : Failure.
374 * #IPC_FAIL [-2] : MmRpc Call failed.
375 * #XDM_EUNSUPPORTED [-3] : Unsupported request.
376 * #OUT_OF_MEMORY [-4] : Out of Shared Memory.
377 */
378 static XDAS_Int32 control(void *codec, int id, void *dynParams, void *status, dce_codec_type codec_id)
379 {
380 MmRpc_FxnCtx fxnCtx;
381 MmRpc_Xlt xltAry[2];
382 int32_t fxnRet;
383 dce_error_status eError = DCE_EOK;
384 dce_codec_control *codec_control_msg = NULL;
386 _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
387 _ASSERT(dynParams != NULL, DCE_EINVALID_INPUT);
388 _ASSERT(status != NULL, DCE_EINVALID_INPUT);
390 /* Allocate Shared/Tiler memory for the codec_control rpc msg structure*/
391 codec_control_msg = memplugin_alloc(sizeof(dce_codec_control), 0, TILER_1D_BUFFER);
393 _ASSERT(codec_control_msg != NULL, DCE_EOUT_OF_MEMORY);
395 /* Populating the msg structure with all the params */
396 codec_control_msg->codec_handle = codec;
397 codec_control_msg->cmd_id = id;
398 codec_control_msg->codec_id = codec_id;
399 codec_control_msg->dyn_params = dynParams;
400 codec_control_msg->status = status;
402 /* Marshall function arguments into the send buffer */
403 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_CONTROL, 1, 2, xltAry);
404 Fill_MmRpc_fxnCtx_Ptr_Params(fxnCtx.params, sizeof(dce_codec_control), codec_control_msg, NULL);
406 /* Dynamic and status params buffer need translation */
407 Fill_MmRpc_fxnCtx_Xlt_Array(fxnCtx.xltAry, 0, (int32_t)codec_control_msg, (int32_t)&(codec_control_msg->dyn_params), NULL);
408 Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[1]), 0, (int32_t)codec_control_msg, (int32_t)&(codec_control_msg->status), NULL);
410 /* Invoke the Remote function through MmRpc */
411 eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
413 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
415 eError = codec_control_msg->result;
417 EXIT:
418 memplugin_free(codec_control_msg, TILER_1D_BUFFER);
420 return (eError);
421 }
423 /*===============================================================*/
424 /** get_version : Codec control call to get the codec version. This call has been made
425 * separate from control call because it involves an additional version
426 * buffer translation.
427 *
428 * @ param codec [in] : Codec Handle obtained in create() call.
429 * @ param id [in] : Command id for XDM control operation.
430 * @ param dynParams [in] : Dynamic input parameters to Codec.
431 * @ param status [out] : Codec returned status parameters.
432 * @ param codec_id [in] : To differentiate between Encoder and Decoder codecs.
433 * @ return : Status of control() call is returned.
434 * #XDM_EOK [0] : Success.
435 * #XDM_EFAIL [-1] : Failure.
436 * #IPC_FAIL [-2] : MmRpc Call failed.
437 * #XDM_EUNSUPPORTED [-3] : Unsupported request.
438 * #OUT_OF_MEMORY [-4] : Out of Shared Memory.
439 */
440 static XDAS_Int32 get_version(void *codec, void *dynParams, void *status, dce_codec_type codec_id)
441 {
442 MmRpc_FxnCtx fxnCtx;
443 MmRpc_Xlt xltAry[3];
444 int32_t fxnRet;
445 dce_error_status eError = DCE_EOK;
446 dce_codec_get_version *codec_get_version_msg = NULL;
448 _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
449 _ASSERT(dynParams != NULL, DCE_EINVALID_INPUT);
450 _ASSERT(status != NULL, DCE_EINVALID_INPUT);
452 /* Allocate Shared/Tiler memory for the codec_get_version rpc msg structure*/
453 codec_get_version_msg = memplugin_alloc(sizeof(dce_codec_get_version), 0, TILER_1D_BUFFER);
455 _ASSERT(codec_get_version_msg != NULL, DCE_EOUT_OF_MEMORY);
457 /* Populating the msg structure with all the params */
458 codec_get_version_msg->codec_handle = codec;
459 codec_get_version_msg->codec_id = codec_id;
460 codec_get_version_msg->dyn_params = dynParams;
461 codec_get_version_msg->status = status;
462 if( codec_id == OMAP_DCE_VIDDEC3 ) {
463 codec_get_version_msg->version = ((IVIDDEC3_Status *)status)->data.buf;
464 } else if( codec_id == OMAP_DCE_VIDENC2 ) {
465 codec_get_version_msg->version = ((IVIDDEC3_Status *)status)->data.buf;
466 }
468 /* Marshall function arguments into the send buffer */
469 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_CONTROL, 1, 3, xltAry);
470 Fill_MmRpc_fxnCtx_Ptr_Params(fxnCtx.params, sizeof(dce_codec_get_version), codec_get_version_msg, NULL);
472 /* Dynamic, status params and version info buffer need translation */
473 Fill_MmRpc_fxnCtx_Xlt_Array(fxnCtx.xltAry, 0, (int32_t)codec_get_version_msg, (int32_t)&(codec_get_version_msg->dyn_params), NULL);
474 Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[1]), 0, (int32_t)codec_get_version_msg, (int32_t)&(codec_get_version_msg->status), NULL);
475 Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[2]), 0, (int32_t)codec_get_version_msg, (int32_t)&(codec_get_version_msg->version), NULL);
477 /* Invoke the Remote function through MmRpc */
478 eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
480 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
482 eError = codec_get_version_msg->result;
484 EXIT:
485 memplugin_free(codec_get_version_msg, TILER_1D_BUFFER);
487 return (eError);
488 }
490 typedef enum process_call_params {
491 CODEC_HANDLE_INDEX = 0,
492 INBUFS_INDEX,
493 OUTBUFS_INDEX,
494 INARGS_INDEX,
495 OUTARGS_INDEX,
496 CODEC_ID_INDEX
497 } process_call_params;
499 /*===============================================================*/
500 /** process : Encode/Decode process.
501 *
502 * @ param codec [in] : Codec Handle obtained in create() call.
503 * @ param inBufs [in] : Input buffer details.
504 * @ param outBufs [in] : Output buffer details.
505 * @ param inArgs [in] : Input arguments.
506 * @ param outArgs [out] : Output arguments.
507 * @ param codec_id [in] : To differentiate between Encoder and Decoder codecs.
508 * @ return : Status of the process call.
509 * #XDM_EOK [0] : Success.
510 * #XDM_EFAIL [-1] : Failure.
511 * #IPC_FAIL [-2] : MmRpc Call failed.
512 * #XDM_EUNSUPPORTED [-3] : Unsupported request.
513 */
514 static XDAS_Int32 process(void *codec, void *inBufs, void *outBufs,
515 void *inArgs, void *outArgs, dce_codec_type codec_id)
516 {
517 MmRpc_FxnCtx fxnCtx;
518 MmRpc_Xlt xltAry[MAX_TOTAl_BUF];
519 int fxnRet, count, total_count, numInBufs = 0, numOutBufs = 0, sz[5] = { 0 };
520 dce_error_status eError = DCE_EOK;
522 _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
523 _ASSERT(inBufs != NULL, DCE_EINVALID_INPUT);
524 _ASSERT(outBufs != NULL, DCE_EINVALID_INPUT);
525 _ASSERT(inArgs != NULL, DCE_EINVALID_INPUT);
526 _ASSERT(outArgs != NULL, DCE_EINVALID_INPUT);
528 if( codec_id == OMAP_DCE_VIDDEC3 ) {
529 numInBufs = ((XDM2_BufDesc *)inBufs)->numBufs;
530 numOutBufs = ((XDM2_BufDesc *)outBufs)->numBufs;
531 sz[INBUFS_INDEX] = sizeof(XDM2_BufDesc);
532 sz[OUTBUFS_INDEX] = sizeof(XDM2_BufDesc);
533 sz[INARGS_INDEX] = sizeof(VIDDEC3_InArgs);
534 sz[OUTARGS_INDEX] = sizeof(VIDDEC3_OutArgs);
535 } else if( codec_id == OMAP_DCE_VIDENC2 ) {
536 numInBufs = ((IVIDEO2_BufDesc *)inBufs)->numPlanes;
537 numOutBufs = ((XDM2_BufDesc *)outBufs)->numBufs;
538 sz[INBUFS_INDEX] = sizeof(IVIDEO2_BufDesc);
539 sz[OUTBUFS_INDEX] = sizeof(XDM2_BufDesc);
540 sz[INARGS_INDEX] = sizeof(VIDENC2_InArgs);
541 sz[OUTARGS_INDEX] = sizeof(VIDENC2_OutArgs);
542 }
544 /* marshall function arguments into the send buffer */
545 /* Approach [2] as explained in "Notes" used for process */
546 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_PROCESS, 6, numInBufs + numOutBufs, xltAry);
547 Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[CODEC_HANDLE_INDEX]), sizeof(int32_t), (int32_t)codec);
548 Fill_MmRpc_fxnCtx_Ptr_Params(&(fxnCtx.params[INBUFS_INDEX]), sz[INBUFS_INDEX], inBufs, NULL);
549 Fill_MmRpc_fxnCtx_Ptr_Params(&(fxnCtx.params[OUTBUFS_INDEX]), sz[OUTBUFS_INDEX], outBufs, NULL);
550 Fill_MmRpc_fxnCtx_Ptr_Params(&(fxnCtx.params[INARGS_INDEX]), sz[INARGS_INDEX], inArgs, NULL);
551 Fill_MmRpc_fxnCtx_Ptr_Params(&(fxnCtx.params[OUTARGS_INDEX]), sz[OUTARGS_INDEX], outArgs, NULL);
552 Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[CODEC_ID_INDEX]), sizeof(int32_t), codec_id);
554 /* InBufs, OutBufs, InArgs, OutArgs buffer need translation but since they have been */
555 /* individually mentioned as fxnCtx Params, they need not be mentioned below again */
556 /* Input and Output Buffers have to be mentioned for translation */
557 for( count = 0, total_count = 0; count < numInBufs; count++, total_count++ ) {
558 if( codec_id == OMAP_DCE_VIDDEC3 ) {
559 Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), INBUFS_INDEX, (int32_t)inBufs, (int32_t)&(((XDM2_BufDesc *)inBufs)->descs[count].buf), NULL);
560 } else if( codec_id == OMAP_DCE_VIDENC2 ) {
561 Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), INBUFS_INDEX, (int32_t)inBufs, (int32_t)&(((IVIDEO2_BufDesc *)inBufs)->planeDesc[count].buf), NULL);
562 }
563 }
565 for( count = 0; count < numOutBufs; count++, total_count++ ) {
566 Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), OUTBUFS_INDEX, (int32_t)outBufs, (int32_t)&(((XDM2_BufDesc *)outBufs)->descs[count].buf), NULL);
567 }
569 /* Invoke the Remote function through MmRpc */
570 eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
572 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
574 eError = (dce_error_status)(fxnRet);
575 EXIT:
576 return (eError);
577 }
579 /*===============================================================*/
580 /** delete : Delete Encode/Decode codec instance.
581 *
582 * @ param codec [in] : Codec Handle obtained in create() call.
583 * @ param codec_id [in] : To differentiate between Encoder and Decoder codecs.
584 * @ return : NIL.
585 */
586 static void delete(void *codec, dce_codec_type codec_id)
587 {
588 MmRpc_FxnCtx fxnCtx;
589 int32_t fxnRet;
590 dce_error_status eError = DCE_EOK;
591 dce_codec_delete *codec_delete_msg = NULL;
593 _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
595 /* Allocate Shared/Tiler memory for the codec_delete rpc msg structure*/
596 codec_delete_msg = memplugin_alloc(sizeof(dce_codec_delete), 0, TILER_1D_BUFFER);
598 _ASSERT(codec_delete_msg != NULL, DCE_EOUT_OF_MEMORY);
600 /* Populating the msg structure with all the params */
601 codec_delete_msg->codec_handle = codec;
602 codec_delete_msg->codec_id = codec_id;
604 /* Marshall function arguments into the send buffer */
605 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_DELETE, 1, 0, NULL);
606 Fill_MmRpc_fxnCtx_Ptr_Params(fxnCtx.params, sizeof(dce_codec_delete), codec_delete_msg, NULL);
608 /* Invoke the Remote function through MmRpc */
609 eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
611 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
613 EXIT:
614 memplugin_free(codec_delete_msg, TILER_1D_BUFFER);
616 return;
617 }
619 /*************** Deocder Codec Engine Functions ***********************/
620 VIDDEC3_Handle VIDDEC3_create(Engine_Handle engine, String name,
621 VIDDEC3_Params *params)
622 {
623 VIDDEC3_Handle codec;
625 DEBUG(">> engine=%p, name=%s, params=%p", engine, name, params);
626 codec = create(engine, name, params, OMAP_DCE_VIDDEC3);
627 DEBUG("<< codec=%p", codec);
628 return (codec);
629 }
631 XDAS_Int32 VIDDEC3_control(VIDDEC3_Handle codec, VIDDEC3_Cmd id,
632 VIDDEC3_DynamicParams *dynParams, VIDDEC3_Status *status)
633 {
634 XDAS_Int32 ret;
636 DEBUG(">> codec=%p, id=%d, dynParams=%p, status=%p",
637 codec, id, dynParams, status);
638 if( id == XDM_GETVERSION ) {
639 ret = get_version(codec, dynParams, status, OMAP_DCE_VIDDEC3);
640 } else {
641 ret = control(codec, id, dynParams, status, OMAP_DCE_VIDDEC3);
642 }
643 DEBUG("<< ret=%d", ret);
644 return (ret);
645 }
647 XDAS_Int32 VIDDEC3_process(VIDDEC3_Handle codec,
648 XDM2_BufDesc *inBufs, XDM2_BufDesc *outBufs,
649 VIDDEC3_InArgs *inArgs, VIDDEC3_OutArgs *outArgs)
650 {
651 XDAS_Int32 ret;
653 DEBUG(">> codec=%p, inBufs=%p, outBufs=%p, inArgs=%p, outArgs=%p",
654 codec, inBufs, outBufs, inArgs, outArgs);
655 ret = process(codec, inBufs, outBufs, inArgs, outArgs, OMAP_DCE_VIDDEC3);
656 DEBUG("<< ret=%d", ret);
657 return (ret);
658 }
660 Void VIDDEC3_delete(VIDDEC3_Handle codec)
661 {
662 DEBUG(">> codec=%p", codec);
663 delete(codec, OMAP_DCE_VIDDEC3);
664 DEBUG("<<");
665 }
667 /*************** Enocder Codec Engine Functions ***********************/
668 VIDENC2_Handle VIDENC2_create(Engine_Handle engine, String name,
669 VIDENC2_Params *params)
670 {
671 VIDENC2_Handle codec;
673 DEBUG(">> engine=%p, name=%s, params=%p", engine, name, params);
674 codec = create(engine, name, params, OMAP_DCE_VIDENC2);
675 DEBUG("<< codec=%p", codec);
676 return (codec);
677 }
679 XDAS_Int32 VIDENC2_control(VIDENC2_Handle codec, VIDENC2_Cmd id,
680 VIDENC2_DynamicParams *dynParams, VIDENC2_Status *status)
681 {
682 XDAS_Int32 ret;
684 DEBUG(">> codec=%p, id=%d, dynParams=%p, status=%p",
685 codec, id, dynParams, status);
686 ret = control(codec, id, dynParams, status, OMAP_DCE_VIDENC2);
687 DEBUG("<< ret=%d", ret);
688 return (ret);
689 }
691 XDAS_Int32 VIDENC2_process(VIDENC2_Handle codec,
692 IVIDEO2_BufDesc *inBufs, XDM2_BufDesc *outBufs,
693 VIDENC2_InArgs *inArgs, VIDENC2_OutArgs *outArgs)
694 {
695 XDAS_Int32 ret;
697 DEBUG(">> codec=%p, inBufs=%p, outBufs=%p, inArgs=%p, outArgs=%p",
698 codec, inBufs, outBufs, inArgs, outArgs);
699 ret = process(codec, inBufs, outBufs, inArgs, outArgs, OMAP_DCE_VIDENC2);
700 DEBUG("<< ret=%d", ret);
701 return (ret);
702 }
704 Void VIDENC2_delete(VIDENC2_Handle codec)
705 {
706 DEBUG(">> codec=%p", codec);
707 delete(codec, OMAP_DCE_VIDENC2);
708 DEBUG("<<");
709 }