4e18039d6d2ac127de9a8cf3bfb2101c2f6d4cfe
[glsdk/libdce2.git] / libdce.c
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)
119     fxnCtx->fxn_id = fxn_id;
120     fxnCtx->num_params = num_params;
121     fxnCtx->num_xlts = num_xlts;
122     fxnCtx->xltAry = xltAry;
125 static inline void Fill_MmRpc_fxnCtx_Ptr_Params(MmRpc_Param *mmrpc_params, int size, void *addr, void *handle)
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;
133 static inline void Fill_MmRpc_fxnCtx_Scalar_Params(MmRpc_Param *mmrpc_params, int size, int data)
135     mmrpc_params->type = MmRpc_ParamType_Scalar;
136     mmrpc_params->param.scalar.size = size;
137     mmrpc_params->param.scalar.data = (size_t)data;
140 static inline void Fill_MmRpc_fxnCtx_Xlt_Array(MmRpc_Xlt *mmrpc_xlt, int index, int32_t base, int32_t addr, void *handle)
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; //*((void *)addr);
148     mmrpc_xlt->handle = (size_t)handle;
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)
156     return (memplugin_alloc(sz, 0, TILER_1D_BUFFER));
159 void dce_free(void *ptr)
161     memplugin_free(ptr, TILER_1D_BUFFER);
164 /*************** Startup/Shutdown Functions ***********************/
165 static int dce_init(void)
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);
191 static void dce_deinit(void)
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;
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)
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);
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)
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;
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)
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);
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)
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);
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)
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);
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)
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);
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)
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;
619 /*************** Deocder Codec Engine Functions ***********************/
620 VIDDEC3_Handle VIDDEC3_create(Engine_Handle engine, String name,
621                               VIDDEC3_Params *params)
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);
631 XDAS_Int32 VIDDEC3_control(VIDDEC3_Handle codec, VIDDEC3_Cmd id,
632                            VIDDEC3_DynamicParams *dynParams, VIDDEC3_Status *status)
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);
647 XDAS_Int32 VIDDEC3_process(VIDDEC3_Handle codec,
648                            XDM2_BufDesc *inBufs, XDM2_BufDesc *outBufs,
649                            VIDDEC3_InArgs *inArgs, VIDDEC3_OutArgs *outArgs)
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);
660 Void VIDDEC3_delete(VIDDEC3_Handle codec)
662     DEBUG(">> codec=%p", codec);
663     delete(codec, OMAP_DCE_VIDDEC3);
664     DEBUG("<<");
667 /*************** Enocder Codec Engine Functions ***********************/
668 VIDENC2_Handle VIDENC2_create(Engine_Handle engine, String name,
669                               VIDENC2_Params *params)
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);
679 XDAS_Int32 VIDENC2_control(VIDENC2_Handle codec, VIDENC2_Cmd id,
680                            VIDENC2_DynamicParams *dynParams, VIDENC2_Status *status)
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);
691 XDAS_Int32 VIDENC2_process(VIDENC2_Handle codec,
692                            IVIDEO2_BufDesc *inBufs, XDM2_BufDesc *outBufs,
693                            VIDENC2_InArgs *inArgs, VIDENC2_OutArgs *outArgs)
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);
704 Void VIDENC2_delete(VIDENC2_Handle codec)
706     DEBUG(">> codec=%p", codec);
707     delete(codec, OMAP_DCE_VIDENC2);
708     DEBUG("<<");