[DCE_TEST] Add Input argument to take in number of frames to write.
[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;
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);
227     _ASSERT(ec != NULL, DCE_EINVALID_INPUT);
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());
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);
237     _ASSERT_AND_EXECUTE(engine_open_msg != NULL, DCE_EOUT_OF_MEMORY, eng_handle = NULL);
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;
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);
248     /* Invoke the Remote function through MmRpc */
249     eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
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);
254     /* Populate return arguments */
255     eng_handle = engine_open_msg->eng_handle;
256     ec[0] = engine_open_msg->error_code;
258 EXIT:
259     memplugin_free(engine_open_msg, TILER_1D_BUFFER);
261     return (eng_handle);
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)
271     MmRpc_FxnCtx        fxnCtx;
272     int32_t             fxnRet;
273     dce_error_status    eError = DCE_EOK;
274     dce_engine_close   *engine_close_msg = NULL;
276     _ASSERT(engine != NULL, DCE_EINVALID_INPUT);
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);
281     _ASSERT(engine_close_msg != NULL, DCE_EOUT_OF_MEMORY);
283     /* Populating the msg structure with all the params */
284     engine_close_msg->eng_handle = engine;
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);
290     /* Invoke the Remote function through MmRpc */
291     eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
293     _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
295 EXIT:
296     memplugin_free(engine_close_msg, TILER_1D_BUFFER);
298     dce_deinit();
299     return;
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)
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;
325     _ASSERT(name != '\0', DCE_EINVALID_INPUT);
326     _ASSERT(engine != NULL, DCE_EINVALID_INPUT);
327     _ASSERT(params != NULL, DCE_EINVALID_INPUT);
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);
332     _ASSERT_AND_EXECUTE(codec_create_msg != NULL, DCE_EOUT_OF_MEMORY, codec_handle = NULL);
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;
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);
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);
350     /* Invoke the Remote function through MmRpc */
351     eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
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);
356     codec_handle = codec_create_msg->codec_handle;
358 EXIT:
359     memplugin_free(codec_create_msg, TILER_1D_BUFFER);
361     return (codec_handle);
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)
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;
387     _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
388     _ASSERT(dynParams != NULL, DCE_EINVALID_INPUT);
389     _ASSERT(status != NULL, DCE_EINVALID_INPUT);
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);
394     _ASSERT(codec_control_msg != NULL, DCE_EOUT_OF_MEMORY);
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;
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);
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);
411     /* Invoke the Remote function through MmRpc */
412     eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
414     _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
416     eError = codec_control_msg->result;
418 EXIT:
419     memplugin_free(codec_control_msg, TILER_1D_BUFFER);
421     return (eError);
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)
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;
449     _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
450     _ASSERT(dynParams != NULL, DCE_EINVALID_INPUT);
451     _ASSERT(status != NULL, DCE_EINVALID_INPUT);
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);
456     _ASSERT(codec_get_version_msg != NULL, DCE_EOUT_OF_MEMORY);
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     }
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);
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);
478     /* Invoke the Remote function through MmRpc */
479     eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
481     _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
483     eError = codec_get_version_msg->result;
485 EXIT:
486     memplugin_free(codec_get_version_msg, TILER_1D_BUFFER);
488     return (eError);
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;
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)
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;
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);
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     }
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);
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     }
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     }
570     /* Invoke the Remote function through MmRpc */
571     eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
573     _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
575     eError = (dce_error_status)(fxnRet);
576 EXIT:
577     return (eError);
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)
589     MmRpc_FxnCtx        fxnCtx;
590     int32_t             fxnRet;
591     dce_error_status    eError = DCE_EOK;
592     dce_codec_delete   *codec_delete_msg = NULL;
594     _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
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);
599     _ASSERT(codec_delete_msg != NULL, DCE_EOUT_OF_MEMORY);
601     /* Populating the msg structure with all the params */
602     codec_delete_msg->codec_handle = codec;
603     codec_delete_msg->codec_id = codec_id;
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);
609     /* Invoke the Remote function through MmRpc */
610     eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
612     _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
614 EXIT:
615     memplugin_free(codec_delete_msg, TILER_1D_BUFFER);
617     return;
620 /*************** Deocder Codec Engine Functions ***********************/
621 VIDDEC3_Handle VIDDEC3_create(Engine_Handle engine, String name,
622                               VIDDEC3_Params *params)
624     VIDDEC3_Handle    codec;
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);
632 XDAS_Int32 VIDDEC3_control(VIDDEC3_Handle codec, VIDDEC3_Cmd id,
633                            VIDDEC3_DynamicParams *dynParams, VIDDEC3_Status *status)
635     XDAS_Int32    ret;
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);
648 XDAS_Int32 VIDDEC3_process(VIDDEC3_Handle codec,
649                            XDM2_BufDesc *inBufs, XDM2_BufDesc *outBufs,
650                            VIDDEC3_InArgs *inArgs, VIDDEC3_OutArgs *outArgs)
652     XDAS_Int32    ret;
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);
661 Void VIDDEC3_delete(VIDDEC3_Handle codec)
663     DEBUG(">> codec=%p", codec);
664     delete(codec, OMAP_DCE_VIDDEC3);
665     DEBUG("<<");
668 /*************** Enocder Codec Engine Functions ***********************/
669 VIDENC2_Handle VIDENC2_create(Engine_Handle engine, String name,
670                               VIDENC2_Params *params)
672     VIDENC2_Handle    codec;
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);
680 XDAS_Int32 VIDENC2_control(VIDENC2_Handle codec, VIDENC2_Cmd id,
681                            VIDENC2_DynamicParams *dynParams, VIDENC2_Status *status)
683     XDAS_Int32    ret;
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);
692 XDAS_Int32 VIDENC2_process(VIDENC2_Handle codec,
693                            IVIDEO2_BufDesc *inBufs, XDM2_BufDesc *outBufs,
694                            VIDENC2_InArgs *inArgs, VIDENC2_OutArgs *outArgs)
696     XDAS_Int32    ret;
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);
705 Void VIDENC2_delete(VIDENC2_Handle codec)
707     DEBUG(">> codec=%p", codec);
708     delete(codec, OMAP_DCE_VIDENC2);
709     DEBUG("<<");