25d0789c48222d9e5ea287c840e75c5764ce07ce
[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 <errno.h>
70 #include <fcntl.h>        /* For O_* constants */
71 #include <sys/stat.h>     /* For mode constants */
72 #include <semaphore.h>
74 /* IPC Headers */
75 #include <MmRpc.h>
77 /*DCE Headers */
78 #include "libdce.h"
79 #include "dce_rpc.h"
80 #include "dce_priv.h"
81 #include "memplugin.h"
84 /********************* GLOBALS ***********************/
85 /* Hande used for Remote Communication                               */
86 static MmRpc_Handle    MmRpcHandle = NULL;
87 sem_t                 *dce_semaphore = NULL;
88 static int             count = 0;
91 /****************** INLINE FUNCTIONS ********************/
93 static inline void Fill_MmRpc_fxnCtx(MmRpc_FxnCtx *fxnCtx, int fxn_id, int num_params, int num_xlts, MmRpc_Xlt *xltAry)
94 {
95     fxnCtx->fxn_id = fxn_id;
96     fxnCtx->num_params = num_params;
97     fxnCtx->num_xlts = num_xlts;
98     fxnCtx->xltAry = xltAry;
99 }
101 static inline void Fill_MmRpc_fxnCtx_OffPtr_Params(MmRpc_Param *mmrpc_params, int size, void *base, int offset, size_t handle)
103     mmrpc_params->type = MmRpc_ParamType_OffPtr;
104     mmrpc_params->param.offPtr.size = (size_t)size;
105     mmrpc_params->param.offPtr.base = (size_t)base;
106     mmrpc_params->param.offPtr.offset = (size_t)offset;
107     mmrpc_params->param.offPtr.handle = handle;
110 static inline void Fill_MmRpc_fxnCtx_Ptr_Params(MmRpc_Param *mmrpc_params, int size, void *addr, size_t handle)
112     mmrpc_params->type = MmRpc_ParamType_Ptr;
113     mmrpc_params->param.ptr.size = size;
114     mmrpc_params->param.ptr.addr = (size_t)addr;
115     mmrpc_params->param.ptr.handle = handle;
118 static inline void Fill_MmRpc_fxnCtx_Scalar_Params(MmRpc_Param *mmrpc_params, int size, int data)
120     mmrpc_params->type = MmRpc_ParamType_Scalar;
121     mmrpc_params->param.scalar.size = size;
122     mmrpc_params->param.scalar.data = (size_t)data;
125 static inline void Fill_MmRpc_fxnCtx_Xlt_Array(MmRpc_Xlt *mmrpc_xlt, int index, int32_t base, int32_t addr, size_t handle)
127     /* index : index of params filled in FxnCtx                                                                                        */
128     /* offset : calculated from address of index                                                                                      */
129     mmrpc_xlt->index = index;
130     mmrpc_xlt->offset = MmRpc_OFFSET(base, addr);
131     mmrpc_xlt->base = handle;
132     mmrpc_xlt->handle = handle;
135 /************************ FUNCTIONS **************************/
136 /* Interface for QNX for parameter buffer allocation                                      */
137 /* These interfaces are implemented to maintain Backward Compatability          */
138 void *dce_alloc(int sz)
140     return (memplugin_alloc(sz, 0, TILER_1D_BUFFER));
143 void dce_free(void *ptr)
145     memplugin_free(ptr, TILER_1D_BUFFER);
148 /*=====================================================================================*/
149 /** dce_ipc_init            : Initialize MmRpc. This function is called within Engine_open().
150  *
151  * @ return                 : Error Status.
152  */
153 static int dce_ipc_init(void)
155     MmRpc_Params        args;
156     dce_error_status    eError = DCE_EOK;
158     printf(" >> dce_ipc_init\n");
160     count++;
161     /* Check if already Initialized */
162     _ASSERT(count == 1, DCE_EOK);
164     /* Create remote server insance */
165     MmRpc_Params_init(&args);
167     eError = MmRpc_create(DCE_DEVICE_NAME, &args, &MmRpcHandle);
169     _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CREATE_FAIL, count--);
171     printf("open(/dev/" DCE_DEVICE_NAME ") -> 0x%x\n", (int)MmRpcHandle);
173 EXIT:
174     return (eError);
177 /*=====================================================================================*/
178 /** dce_ipc_deinit            : DeInitialize MmRpc. This function is called within
179  *                              Engine_close().
180  */
181 static void dce_ipc_deinit()
183     count--;
184     if( count > 0 ) {
185         goto EXIT;
186     }
188     if( MmRpcHandle != NULL ) {
189         MmRpc_delete(&MmRpcHandle);
190     }
191     MmRpcHandle = NULL;
193 EXIT:
194     return;
197 /*===============================================================*/
198 /** Engine_open        : Open Codec Engine.
199  *
200  * @ param attrs  [in]       : Engine Attributes. This param is not passed to Remote core.
201  * @ param name [in]       : Name of Encoder or Decoder codec.
202  * @ param ec [out]         : Error returned by Codec Engine.
203  * @ return : Codec Engine Handle is returned to be used to create codec.
204  *                 In case of error, NULL is returned as Engine Handle.
205  */
206 Engine_Handle Engine_open(String name, Engine_Attrs *attrs, Engine_Error *ec)
208     MmRpc_FxnCtx        fxnCtx;
209     dce_error_status    eError = DCE_EOK;
210     dce_engine_open    *engine_open_msg = NULL;
211     Engine_Attrs       *engine_attrs = NULL;
212     Engine_Handle       engine_handle = NULL;
214     _ASSERT(name != '\0', DCE_EINVALID_INPUT);
216     if( dce_semaphore == NULL ) {
217         _ASSERT((dce_semaphore = sem_open("/dce_semaphore", O_CREAT, S_IRWXU | S_IRWXO | S_IRWXG, 1)) != SEM_FAILED, DCE_ESEMAPHORE_FAIL);
218     }
219     /* Lock dce_ipc_init() and Engine_open() IPU call to prevent hang*/
220     _ASSERT(sem_wait(dce_semaphore) == DCE_EOK, DCE_ESEMAPHORE_FAIL);
222     /* Initialize IPC. In case of Error Deinitialize them */
223     _ASSERT_AND_EXECUTE(dce_ipc_init() == DCE_EOK, DCE_EIPC_CREATE_FAIL, dce_ipc_deinit());
225     printf(">> Engine_open Params::name = %s size = %d\n", name, strlen(name));
226     /* Allocate Shared memory for the engine_open rpc msg structure*/
227     /* Tiler Memory preferred in QNX */
228     engine_open_msg = memplugin_alloc(sizeof(dce_engine_open), 0, TILER_1D_BUFFER);
229     _ASSERT_AND_EXECUTE(engine_open_msg != NULL, DCE_EOUT_OF_MEMORY, engine_handle = NULL);
231     if( attrs ) {
232         engine_attrs = memplugin_alloc(sizeof(Engine_Attrs), 0, TILER_1D_BUFFER);
233         _ASSERT_AND_EXECUTE(engine_attrs != NULL, DCE_EOUT_OF_MEMORY, engine_handle = NULL);
234         *engine_attrs = *attrs;
235     }
236     /* Populating the msg structure with all the params */
237     /* Populating all params into a struct avoid individual address translations of name, ec */
238     strncpy(engine_open_msg->name, name, strlen(name));
239     engine_open_msg->engine_attrs = engine_attrs;
241     /* Marshall function arguments into the send buffer */
242     Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_ENGINE_OPEN, 1, 0, NULL);
243     Fill_MmRpc_fxnCtx_OffPtr_Params(fxnCtx.params, GetSz(engine_open_msg), (void *)P2H(engine_open_msg),
244                                     sizeof(MemHeader), memplugin_share(engine_open_msg));
246     /* Invoke the Remote function through MmRpc */
247     eError = MmRpc_call(MmRpcHandle, &fxnCtx, (int32_t *)(&engine_handle));
249     /* In case of Error, the Application will get a NULL Engine Handle */
250     _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CALL_FAIL, engine_handle = NULL);
252     if( ec ) {
253         *ec = engine_open_msg->error_code;
254     }
256 EXIT:
257     /* Unlock dce_ipc_init() and Engine_open() IPU call */
258     _ASSERT(sem_post(dce_semaphore) == DCE_EOK, DCE_ESEMAPHORE_FAIL);
260     memplugin_free(engine_open_msg, TILER_1D_BUFFER);
261     if( engine_attrs ) {
262         memplugin_free(engine_attrs, TILER_1D_BUFFER);
263     }
264     return ((Engine_Handle)engine_handle);
267 /*===============================================================*/
268 /** Engine_close           : Close Engine.
269  *
270  * @ param engine  [in]    : Engine Handle obtained in Engine_open() call.
271  */
272 Void Engine_close(Engine_Handle engine)
274     MmRpc_FxnCtx        fxnCtx;
275     int32_t             fxnRet;
276     dce_error_status    eError = DCE_EOK;
278     _ASSERT(engine != NULL, DCE_EINVALID_INPUT);
280     /* Lock dce_ipc_deinit() and Engine_close() IPU call */
281     _ASSERT(sem_wait(dce_semaphore) == DCE_EOK, DCE_ESEMAPHORE_FAIL);
283     /* Marshall function arguments into the send buffer */
284     Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_ENGINE_CLOSE, 1, 0, NULL);
285     Fill_MmRpc_fxnCtx_Scalar_Params(fxnCtx.params, sizeof(Engine_Handle), (int32_t)engine);
287     /* Invoke the Remote function through MmRpc */
288     eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
290     _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
292 EXIT:
293     dce_ipc_deinit();
295     /* Unlock dce_ipc_deinit() and Engine_close() IPU call */
296     _ASSERT(sem_post(dce_semaphore) == DCE_EOK, DCE_ESEMAPHORE_FAIL);
297     sem_close(dce_semaphore);
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     dce_error_status    eError = DCE_EOK;
320     void               *codec_handle = NULL;
321     char               *codec_name = NULL;
323     _ASSERT(name != '\0', DCE_EINVALID_INPUT);
324     _ASSERT(engine != NULL, DCE_EINVALID_INPUT);
325     _ASSERT(params != NULL, DCE_EINVALID_INPUT);
327     /* Allocate shared memory for translating codec name to IPU */
328     codec_name = memplugin_alloc(MAX_NAME_LENGTH * sizeof(char), 0, TILER_1D_BUFFER);
329     _ASSERT_AND_EXECUTE(codec_name != NULL, DCE_EOUT_OF_MEMORY, codec_handle = NULL);
331     strncpy(codec_name, name, strlen(name));
333     /* Marshall function arguments into the send buffer */
334     Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_CREATE, 4, 0, NULL);
335     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[0]), sizeof(int32_t), codec_id);
336     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[1]), sizeof(Engine_Handle), (int32_t)engine);
337     Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[2]), GetSz(codec_name), P2H(codec_name),
338                                     sizeof(MemHeader), memplugin_share(codec_name));
339     Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[3]), GetSz(params), P2H(params),
340                                     sizeof(MemHeader),  memplugin_share(params));
341     /* Invoke the Remote function through MmRpc */
342     eError = MmRpc_call(MmRpcHandle, &fxnCtx, (int32_t *)(&codec_handle));
344     /* In case of Error, the Application will get a NULL Codec Handle */
345     _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CALL_FAIL, codec_handle = NULL);
347 EXIT:
348     memplugin_free(codec_name, TILER_1D_BUFFER);
349     return ((void *)codec_handle);
352 /*===============================================================*/
353 /** control               : Codec control call.
354  *
355  * @ param codec  [in]     : Codec Handle obtained in create() call.
356  * @ param id [in]            : Command id for XDM control operation.
357  * @ param dynParams [in] : Dynamic input parameters to Codec.
358  * @ param status [out]    : Codec returned status parameters.
359  * @ param codec_id [in]  : To differentiate between Encoder and Decoder codecs.
360  * @ return : Status of control() call is returned.
361  *                #XDM_EOK                  [0]   :  Success.
362  *                #XDM_EFAIL                [-1] :  Failure.
363  *                #IPC_FAIL                   [-2] : MmRpc Call failed.
364  *                #XDM_EUNSUPPORTED [-3] :  Unsupported request.
365  *                #OUT_OF_MEMORY       [-4] :  Out of Shared Memory.
366  */
367 static XDAS_Int32 control(void *codec, int id, void *dynParams, void *status, dce_codec_type codec_id)
369     MmRpc_FxnCtx        fxnCtx;
370     int32_t             fxnRet;
371     dce_error_status    eError = DCE_EOK;
373     _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
374     _ASSERT(dynParams != NULL, DCE_EINVALID_INPUT);
375     _ASSERT(status != NULL, DCE_EINVALID_INPUT);
377     /* Marshall function arguments into the send buffer */
378     Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_CONTROL, 5, 0, NULL);
379     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[0]), sizeof(int32_t), codec_id);
380     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[1]), sizeof(int32_t), (int32_t)codec);
381     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[2]), sizeof(int32_t), (int32_t)id);
382     Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[3]), GetSz(dynParams), P2H(dynParams),
383                                     sizeof(MemHeader), memplugin_share(dynParams));
384     Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[4]), GetSz(status), P2H(status),
385                                     sizeof(MemHeader), memplugin_share(status));
387     /* Invoke the Remote function through MmRpc */
388     eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
390     _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
392 EXIT:
393     return (fxnRet);
397 /*===============================================================*/
398 /** get_version        : Codec control call to get the codec version. This call has been made
399  *                                     separate from control call because it involves an additional version
400  *                                     buffer translation.
401  *
402  * @ param codec  [in]     : Codec Handle obtained in create() call.
403  * @ param id [in]            : Command id for XDM control operation.
404  * @ param dynParams [in] : Dynamic input parameters to Codec.
405  * @ param status [out]    : Codec returned status parameters.
406  * @ param codec_id [in]  : To differentiate between Encoder and Decoder codecs.
407  * @ return : Status of control() call is returned.
408  *                #XDM_EOK                  [0]   :  Success.
409  *                #XDM_EFAIL                [-1] :  Failure.
410  *                #IPC_FAIL                   [-2] : MmRpc Call failed.
411  *                #XDM_EUNSUPPORTED [-3] :  Unsupported request.
412  *                #OUT_OF_MEMORY       [-4] :  Out of Shared Memory.
413  */
414 static XDAS_Int32 get_version(void *codec, void *dynParams, void *status, dce_codec_type codec_id)
416     MmRpc_FxnCtx        fxnCtx;
417     MmRpc_Xlt           xltAry;
418     void             * *version_buf = NULL;
419     int32_t             fxnRet;
420     dce_error_status    eError = DCE_EOK;
422     _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
423     _ASSERT(dynParams != NULL, DCE_EINVALID_INPUT);
424     _ASSERT(status != NULL, DCE_EINVALID_INPUT);
426     if( codec_id == OMAP_DCE_VIDDEC3 ) {
427         version_buf = (void * *)(&(((IVIDDEC3_Status *)status)->data.buf));
428     } else if( codec_id == OMAP_DCE_VIDENC2 ) {
429         version_buf = (void * *)(&(((IVIDENC2_Status *)status)->data.buf));
430     }
431     _ASSERT(*version_buf != NULL, DCE_EINVALID_INPUT);
433     /* Marshall function arguments into the send buffer */
434     Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_GET_VERSION, 4, 1, &xltAry);
435     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[0]), sizeof(int32_t), codec_id);
436     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[1]), sizeof(int32_t), (int32_t)codec);
437     Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[2]), GetSz(dynParams), P2H(dynParams),
438                                     sizeof(MemHeader), memplugin_share(dynParams));
439     Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[3]), GetSz(status), P2H(status),
440                                     sizeof(MemHeader), memplugin_share(status));
442     /* Address Translation needed for buffer for version Info */
443     Fill_MmRpc_fxnCtx_Xlt_Array(fxnCtx.xltAry, 3, (int32_t)status, (int32_t)version_buf, memplugin_share(*version_buf));
445     /* Invoke the Remote function through MmRpc */
446     eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
448     _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
450 EXIT:
451     return (fxnRet);
454 typedef enum process_call_params {
455     CODEC_ID_INDEX = 0,
456     CODEC_HANDLE_INDEX,
457     INBUFS_INDEX,
458     OUTBUFS_INDEX,
459     INARGS_INDEX,
460     OUTARGS_INDEX
461 } process_call_params;
463 #define LUMA_BUF 0
464 #define CHROMA_BUF 1
465 /*===============================================================*/
466 /** process               : Encode/Decode process.
467  *
468  * @ param codec  [in]     : Codec Handle obtained in create() call.
469  * @ param inBufs [in]     : Input buffer details.
470  * @ param outBufs [in]    : Output buffer details.
471  * @ param inArgs [in]     : Input arguments.
472  * @ param outArgs [out]  : Output arguments.
473  * @ param codec_id [in]  : To differentiate between Encoder and Decoder codecs.
474  * @ return : Status of the process call.
475  *                #XDM_EOK                  [0]   :  Success.
476  *                #XDM_EFAIL                [-1] :  Failure.
477  *                #IPC_FAIL                   [-2] :  MmRpc Call failed.
478  *                #XDM_EUNSUPPORTED [-3] :  Unsupported request.
479  */
480 static XDAS_Int32 process(void *codec, void *inBufs, void *outBufs,
481                           void *inArgs, void *outArgs, dce_codec_type codec_id)
483     MmRpc_FxnCtx        fxnCtx;
484     MmRpc_Xlt           xltAry[MAX_TOTAl_BUF];
485     int                 fxnRet, count, total_count, numInBufs = 0, numOutBufs = 0;
486     dce_error_status    eError = DCE_EOK;
487     void             * *data_buf = NULL;
489     _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
490     _ASSERT(inBufs != NULL, DCE_EINVALID_INPUT);
491     _ASSERT(outBufs != NULL, DCE_EINVALID_INPUT);
492     _ASSERT(inArgs != NULL, DCE_EINVALID_INPUT);
493     _ASSERT(outArgs != NULL, DCE_EINVALID_INPUT);
495     if( codec_id == OMAP_DCE_VIDDEC3 ) {
496         numInBufs = ((XDM2_BufDesc *)inBufs)->numBufs;
497         numOutBufs = ((XDM2_BufDesc *)outBufs)->numBufs;
498     } else if( codec_id == OMAP_DCE_VIDENC2 ) {
499         numInBufs = ((IVIDEO2_BufDesc *)inBufs)->numPlanes;
500         numOutBufs = ((XDM2_BufDesc *)outBufs)->numBufs;
501     }
503     /* marshall function arguments into the send buffer                       */
504     /* Approach [2] as explained in "Notes" used for process               */
505     Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_PROCESS, 6, numInBufs + numOutBufs, xltAry);
506     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[CODEC_ID_INDEX]), sizeof(int32_t), codec_id);
507     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[CODEC_HANDLE_INDEX]), sizeof(int32_t), (int32_t)codec);
509     Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[INBUFS_INDEX]), GetSz(inBufs), P2H(inBufs),
510                                     sizeof(MemHeader), memplugin_share(inBufs));
511     Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[OUTBUFS_INDEX]), GetSz(outBufs), P2H(outBufs),
512                                     sizeof(MemHeader), memplugin_share(outBufs));
513     Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[INARGS_INDEX]), GetSz(inArgs), P2H(inArgs),
514                                     sizeof(MemHeader), memplugin_share(inArgs));
515     Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[OUTARGS_INDEX]), GetSz(outArgs), P2H(outArgs),
516                                     sizeof(MemHeader), memplugin_share(outArgs));
518     /* InBufs, OutBufs, InArgs, OutArgs buffer need translation but since they have been */
519     /* individually mentioned as fxnCtx Params, they need not be mentioned below again */
520     /* Input and Output Buffers have to be mentioned for translation                               */
521     for( count = 0, total_count = 0; count < numInBufs; count++, total_count++ ) {
522         if( codec_id == OMAP_DCE_VIDDEC3 ) {
523             data_buf = (void * *)(&(((XDM2_BufDesc *)inBufs)->descs[count].buf));
524             Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), INBUFS_INDEX, (int32_t)inBufs,
525                                         (int32_t)data_buf, (size_t)*data_buf);
526         } else if( codec_id == OMAP_DCE_VIDENC2 ) {
527             data_buf = (void * *)(&(((IVIDEO2_BufDesc *)inBufs)->planeDesc[count].buf));
528             Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), INBUFS_INDEX, (int32_t)inBufs,
529                                         (int32_t)data_buf, (size_t)*data_buf);
530         }
531     }
533     /* Output Buffers */
534     for( count = 0; count < numOutBufs; count++, total_count++ ) {
535         if(((XDM2_BufDesc *)outBufs)->descs[LUMA_BUF].buf != ((XDM2_BufDesc *)outBufs)->descs[CHROMA_BUF].buf ) {
536             /* Either Encode usecase or MultiPlanar Buffers for Decode usecase */
537             data_buf = (void * *)(&(((XDM2_BufDesc *)outBufs)->descs[count].buf));
538             Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), OUTBUFS_INDEX, (int32_t)outBufs,
539                                         (int32_t)data_buf, (size_t)*data_buf);
540         }
541 #if defined(BUILDOS_LINUX)
542         else {
543             /* SinglePlanar Buffers for Decode usecase*/
544             data_buf = (void * *)(&(((XDM2_BufDesc *)outBufs)->descs[count].buf));
545             Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), OUTBUFS_INDEX, (int32_t)outBufs,
546                                         (int32_t)data_buf, (size_t)*data_buf);
547             if( count == CHROMA_BUF ) {
548                 if(((XDM2_BufDesc *)outBufs)->descs[count].memType == XDM_MEMTYPE_RAW ||
549                    ((XDM2_BufDesc *)outBufs)->descs[count].memType == XDM_MEMTYPE_TILEDPAGE ) {
550                     *data_buf += ((XDM2_BufDesc *)outBufs)->descs[LUMA_BUF].bufSize.bytes;
551                 } else {
552                     *data_buf += ((XDM2_BufDesc *)outBufs)->descs[LUMA_BUF].bufSize.tileMem.width *
553                                  ((XDM2_BufDesc *)outBufs)->descs[LUMA_BUF].bufSize.tileMem.height;
554                 }
555             }
556         }
557 #endif
558     }
560     /* Invoke the Remote function through MmRpc */
561     eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
563     _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
565     eError = (dce_error_status)(fxnRet);
566 EXIT:
567     return (eError);
570 /*===============================================================*/
571 /** delete                : Delete Encode/Decode codec instance.
572  *
573  * @ param codec  [in]     : Codec Handle obtained in create() call.
574  * @ param codec_id [in]  : To differentiate between Encoder and Decoder codecs.
575  * @ return : NIL.
576  */
577 static void delete(void *codec, dce_codec_type codec_id)
579     MmRpc_FxnCtx        fxnCtx;
580     int32_t             fxnRet;
581     dce_error_status    eError = DCE_EOK;
583     _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
585     /* Marshall function arguments into the send buffer */
586     Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_DELETE, 2, 0, NULL);
587     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[0]), sizeof(int32_t), codec_id);
588     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[1]), sizeof(int32_t), (int32_t)codec);
590     /* Invoke the Remote function through MmRpc */
591     eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
593     _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
595 EXIT:
596     return;
599 /*************** Deocder Codec Engine Functions ***********************/
600 VIDDEC3_Handle VIDDEC3_create(Engine_Handle engine, String name,
601                               VIDDEC3_Params *params)
603     VIDDEC3_Handle    codec;
605     DEBUG(">> engine=%p, name=%s, params=%p", engine, name, params);
606     codec = create(engine, name, params, OMAP_DCE_VIDDEC3);
607     DEBUG("<< codec=%p", codec);
608     return (codec);
611 XDAS_Int32 VIDDEC3_control(VIDDEC3_Handle codec, VIDDEC3_Cmd id,
612                            VIDDEC3_DynamicParams *dynParams, VIDDEC3_Status *status)
614     XDAS_Int32    ret;
616     DEBUG(">> codec=%p, id=%d, dynParams=%p, status=%p",
617           codec, id, dynParams, status);
618     if( id == XDM_GETVERSION ) {
619         ret = get_version(codec, dynParams, status, OMAP_DCE_VIDDEC3);
620     } else {
621         ret = control(codec, id, dynParams, status, OMAP_DCE_VIDDEC3);
622     }
623     DEBUG("<< ret=%d", ret);
624     return (ret);
627 XDAS_Int32 VIDDEC3_process(VIDDEC3_Handle codec,
628                            XDM2_BufDesc *inBufs, XDM2_BufDesc *outBufs,
629                            VIDDEC3_InArgs *inArgs, VIDDEC3_OutArgs *outArgs)
631     XDAS_Int32    ret;
633     DEBUG(">> codec=%p, inBufs=%p, outBufs=%p, inArgs=%p, outArgs=%p",
634           codec, inBufs, outBufs, inArgs, outArgs);
635     ret = process(codec, inBufs, outBufs, inArgs, outArgs, OMAP_DCE_VIDDEC3);
636     DEBUG("<< ret=%d", ret);
637     return (ret);
640 Void VIDDEC3_delete(VIDDEC3_Handle codec)
642     DEBUG(">> codec=%p", codec);
643     delete(codec, OMAP_DCE_VIDDEC3);
644     DEBUG("<<");
647 /*************** Enocder Codec Engine Functions ***********************/
648 VIDENC2_Handle VIDENC2_create(Engine_Handle engine, String name,
649                               VIDENC2_Params *params)
651     VIDENC2_Handle    codec;
653     DEBUG(">> engine=%p, name=%s, params=%p", engine, name, params);
654     codec = create(engine, name, params, OMAP_DCE_VIDENC2);
655     DEBUG("<< codec=%p", codec);
656     return (codec);
659 XDAS_Int32 VIDENC2_control(VIDENC2_Handle codec, VIDENC2_Cmd id,
660                            VIDENC2_DynamicParams *dynParams, VIDENC2_Status *status)
662     XDAS_Int32    ret;
664     DEBUG(">> codec=%p, id=%d, dynParams=%p, status=%p",
665           codec, id, dynParams, status);
666     ret = control(codec, id, dynParams, status, OMAP_DCE_VIDENC2);
667     DEBUG("<< ret=%d", ret);
668     return (ret);
671 XDAS_Int32 VIDENC2_process(VIDENC2_Handle codec,
672                            IVIDEO2_BufDesc *inBufs, XDM2_BufDesc *outBufs,
673                            VIDENC2_InArgs *inArgs, VIDENC2_OutArgs *outArgs)
675     XDAS_Int32    ret;
677     DEBUG(">> codec=%p, inBufs=%p, outBufs=%p, inArgs=%p, outArgs=%p",
678           codec, inBufs, outBufs, inArgs, outArgs);
679     ret = process(codec, inBufs, outBufs, inArgs, outArgs, OMAP_DCE_VIDENC2);
680     DEBUG("<< ret=%d", ret);
681     return (ret);
684 Void VIDENC2_delete(VIDENC2_Handle codec)
686     DEBUG(">> codec=%p", codec);
687     delete(codec, OMAP_DCE_VIDENC2);
688     DEBUG("<<");