f83aeb5df0d93977b584f1bb68b33ebbe234e937
[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_LINUX)
75 #include <xf86drm.h>
76 #include <omap_drm.h>
77 #include <omap_drmif.h>
78 #endif /* BUILDOS_LINUX */
80 /* IPC Headers */
81 #include <MmRpc.h>
83 /*DCE Headers */
84 #include "libdce.h"
85 #include "dce_rpc.h"
86 #include "dce_priv.h"
87 #include "memplugin.h"
90 #if defined(BUILDOS_LINUX)
91 int                     fd                 = -1;
92 struct   omap_device   *dev   =  0;
93 uint32_t                dce_debug          =  3;
94 #endif /* BUILDOS_LINUX */
97 /********************* GLOBALS ***********************/
98 /* Hande used for Remote Communication                               */
99 static MmRpc_Handle       MmRpcHandle = NULL;
100 static pthread_mutex_t    mutex = PTHREAD_MUTEX_INITIALIZER;
101 static int                count = 0;
104 /****************** INLINE FUNCTIONS ********************/
106 static inline void Fill_MmRpc_fxnCtx(MmRpc_FxnCtx *fxnCtx, int fxn_id, int num_params, int num_xlts, MmRpc_Xlt *xltAry)
108     fxnCtx->fxn_id = fxn_id;
109     fxnCtx->num_params = num_params;
110     fxnCtx->num_xlts = num_xlts;
111     fxnCtx->xltAry = xltAry;
114 static inline void Fill_MmRpc_fxnCtx_OffPtr_Params(MmRpc_Param *mmrpc_params, int size, void *base, int offset, size_t handle)
116     mmrpc_params->type = MmRpc_ParamType_OffPtr;
117     mmrpc_params->param.offPtr.size = (size_t)size;
118     mmrpc_params->param.offPtr.base = (size_t)base;
119     mmrpc_params->param.offPtr.offset = (size_t)offset;
120     mmrpc_params->param.offPtr.handle = handle;
123 static inline void Fill_MmRpc_fxnCtx_Ptr_Params(MmRpc_Param *mmrpc_params, int size, void *addr, size_t handle)
125     mmrpc_params->type = MmRpc_ParamType_Ptr;
126     mmrpc_params->param.ptr.size = size;
127     mmrpc_params->param.ptr.addr = (size_t)addr;
128     mmrpc_params->param.ptr.handle = handle;
131 static inline void Fill_MmRpc_fxnCtx_Scalar_Params(MmRpc_Param *mmrpc_params, int size, int data)
133     mmrpc_params->type = MmRpc_ParamType_Scalar;
134     mmrpc_params->param.scalar.size = size;
135     mmrpc_params->param.scalar.data = (size_t)data;
138 static inline void Fill_MmRpc_fxnCtx_Xlt_Array(MmRpc_Xlt *mmrpc_xlt, int index, int32_t base, int32_t addr, size_t handle)
140     /* index : index of params filled in FxnCtx                                                                                        */
141     /* offset : calculated from address of index                                                                                      */
142     mmrpc_xlt->index = index;
143     mmrpc_xlt->offset = MmRpc_OFFSET(base, addr);
144     mmrpc_xlt->base = handle;
145     mmrpc_xlt->handle = handle;
148 /************************ FUNCTIONS **************************/
149 /* Interface for QNX for parameter buffer allocation                                */
150 /* These interfaces are implemented to maintain Backward Compatability */
151 void *dce_alloc(int sz)
153     return (memplugin_alloc(sz, 0, TILER_1D_BUFFER));
156 void dce_free(void *ptr)
158     memplugin_free(ptr, TILER_1D_BUFFER);
161 /*************** Startup/Shutdown Functions ***********************/
162 static int dce_init(void)
164     dce_error_status    eError = DCE_EOK;
165     MmRpc_Params        args;
167     printf(" >> dce_init\n");
169     pthread_mutex_lock(&mutex);
171     count++;
172     /* Check if already Initialized */
173     _ASSERT(count == 1, DCE_EOK);
175     /* Create remote server insance */
176     MmRpc_Params_init(&args);
178     eError = MmRpc_create(DCE_DEVICE_NAME, &args, &MmRpcHandle);
180     _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CREATE_FAIL, count--);
182     printf("open(/dev/" DCE_DEVICE_NAME ") -> 0x%x\n", (int)MmRpcHandle);
184 #if defined(BUILDOS_LINUX)
185     /* Open omapdrm device */
187     if(fd == -1) {
188         printf("Open omapdrm device \n");
189         fd = drmOpen("omapdrm", "platform:omapdrm:00");
190     }
191     if( fd >= 0 ) {
192         dev = omap_device_new(fd);
193     } else {
194         printf("Error opening omapdrm : drmOpen failed");
195         goto EXIT;
196     }
197 #endif /* BUILDOS_LINUX */
200 EXIT:
201     pthread_mutex_unlock(&mutex);
202     return (eError);
205 static void dce_deinit(void)
207     pthread_mutex_lock(&mutex);
209     count--;
210     if( count > 0 ) {
211         goto EXIT;
212     }
214     if( MmRpcHandle != NULL ) {
215         MmRpc_delete(&MmRpcHandle);
216     }
217     MmRpcHandle = NULL;
219 #if defined(BUILDOS_LINUX)
220     omap_device_del(dev);
221     dev = NULL;
222     close(fd);
223     fd = -1;
224 #endif /* BUILDOS_LINUX */
227 EXIT:
228     pthread_mutex_unlock(&mutex);
229     return;
232 /* Incase of X11 or Wayland the fd can be shared to libdce using this call */
233 #if defined(BUILDOS_LINUX)
234 void dce_set_fd(int dce_fd)
236     fd = dce_fd;
239 int dce_get_fd(void)
241     return (fd);
244 #endif /* BUILDOS_LINUX */
246 /*===============================================================*/
247 /** Engine_open        : Open Codec Engine.
248  *
249  * @ param attrs  [in]       : Engine Attributes. This param is not passed to Remote core.
250  * @ param name [in]       : Name of Encoder or Decoder codec.
251  * @ param ec [out]         : Error returned by Codec Engine.
252  * @ return : Codec Engine Handle is returned to be used to create codec.
253  *                 In case of error, NULL is returned as Engine Handle.
254  */
255 Engine_Handle Engine_open(String name, Engine_Attrs *attrs, Engine_Error *ec)
257     MmRpc_FxnCtx        fxnCtx;
258     dce_error_status    eError = DCE_EOK;
259     dce_engine_open    *engine_open_msg = NULL;
260     Engine_Attrs       *engine_attrs = NULL;
261     Engine_Handle       engine_handle = NULL;
263     _ASSERT(name != '\0', DCE_EINVALID_INPUT);
265     /* Initialize DCE and IPC. In case of Error Deinitialize them */
266     _ASSERT_AND_EXECUTE(dce_init() == DCE_EOK, DCE_EIPC_CREATE_FAIL, dce_deinit());
268     printf(">> Engine_open Params::name = %s size = %d\n", name, strlen(name));
269     /* Allocate Shared memory for the engine_open rpc msg structure*/
270     /* Tiler Memory preferred in QNX */
271     engine_open_msg = memplugin_alloc(sizeof(dce_engine_open), 0, TILER_1D_BUFFER);
272     _ASSERT_AND_EXECUTE(engine_open_msg != NULL, DCE_EOUT_OF_MEMORY, engine_handle = NULL);
274     if( attrs ) {
275         engine_attrs = memplugin_alloc(sizeof(Engine_Attrs), 0, TILER_1D_BUFFER);
276         _ASSERT_AND_EXECUTE(engine_attrs != NULL, DCE_EOUT_OF_MEMORY, engine_handle = NULL);
277         *engine_attrs = *attrs;
278     }
279     /* Populating the msg structure with all the params */
280     /* Populating all params into a struct avoid individual address translations of name, ec */
281     strncpy(engine_open_msg->name, name, strlen(name));
282     engine_open_msg->engine_attrs = engine_attrs;
284     /* Marshall function arguments into the send buffer */
285     Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_ENGINE_OPEN, 1, 0, NULL);
286     Fill_MmRpc_fxnCtx_OffPtr_Params(fxnCtx.params, GetSz(engine_open_msg), (void *)P2H(engine_open_msg),
287                                     sizeof(MemHeader), memplugin_share(engine_open_msg));
289     /* Invoke the Remote function through MmRpc */
290     eError = MmRpc_call(MmRpcHandle, &fxnCtx, (int32_t *)(&engine_handle));
292     /* In case of Error, the Application will get a NULL Engine Handle */
293     _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CALL_FAIL, engine_handle = NULL);
295     if( ec ) {
296         *ec = engine_open_msg->error_code;
297     }
298 EXIT:
299     memplugin_free(engine_open_msg, TILER_1D_BUFFER);
300     if( engine_attrs ) {
301         memplugin_free(engine_attrs, TILER_1D_BUFFER);
302     }
303     return ((Engine_Handle)engine_handle);
306 /*===============================================================*/
307 /** Engine_close           : Close Engine.
308  *
309  * @ param engine  [in]    : Engine Handle obtained in Engine_open() call.
310  */
311 Void Engine_close(Engine_Handle engine)
313     MmRpc_FxnCtx        fxnCtx;
314     int32_t             fxnRet;
315     dce_error_status    eError = DCE_EOK;
317     _ASSERT(engine != NULL, DCE_EINVALID_INPUT);
319     /* Marshall function arguments into the send buffer */
320     Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_ENGINE_CLOSE, 1, 0, NULL);
321     Fill_MmRpc_fxnCtx_Scalar_Params(fxnCtx.params, sizeof(Engine_Handle), (int32_t)engine);
323     /* Invoke the Remote function through MmRpc */
324     eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
326     _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
328 EXIT:
329     dce_deinit();
330     return;
333 /*===============================================================*/
334 /** Functions create(), control(), get_version(), process(), delete() are common codec
335  * glue function signatures which are same for both encoder and decoder
336  */
337 /*===============================================================*/
338 /** create         : Create Encoder/Decoder codec.
339  *
340  * @ param engine  [in]    : Engine Handle obtained in Engine_open() call.
341  * @ param name [in]       : Name of Encoder or Decoder codec.
342  * @ param params [in]     : Static parameters of codec.
343  * @ param codec_id [in]  : To differentiate between Encoder and Decoder codecs.
344  * @ return : Codec Handle is returned to be used for control, process, delete calls.
345  *                 In case of error, NULL is returned.
346  */
347 static void *create(Engine_Handle engine, String name, void *params, dce_codec_type codec_id)
349     MmRpc_FxnCtx        fxnCtx;
350     dce_error_status    eError = DCE_EOK;
351     void               *codec_handle = NULL;
352     char               *codec_name = NULL;
354     _ASSERT(name != '\0', DCE_EINVALID_INPUT);
355     _ASSERT(engine != NULL, DCE_EINVALID_INPUT);
356     _ASSERT(params != NULL, DCE_EINVALID_INPUT);
358     /* Allocate shared memory for translating codec name to IPU */
359     codec_name = memplugin_alloc(MAX_NAME_LENGTH * sizeof(char), 0, TILER_1D_BUFFER);
360     _ASSERT_AND_EXECUTE(codec_name != NULL, DCE_EOUT_OF_MEMORY, codec_handle = NULL);
362     strncpy(codec_name, name, strlen(name));
364     /* Marshall function arguments into the send buffer */
365     Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_CREATE, 4, 0, NULL);
366     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[0]), sizeof(int32_t), codec_id);
367     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[1]), sizeof(Engine_Handle), (int32_t)engine);
368     Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[2]), GetSz(codec_name), P2H(codec_name),
369                                     sizeof(MemHeader), memplugin_share(codec_name));
370     Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[3]), GetSz(params), P2H(params),
371                                     sizeof(MemHeader),  memplugin_share(params));
372     /* Invoke the Remote function through MmRpc */
373     eError = MmRpc_call(MmRpcHandle, &fxnCtx, (int32_t *)(&codec_handle));
375     /* In case of Error, the Application will get a NULL Codec Handle */
376     _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CALL_FAIL, codec_handle = NULL);
378 EXIT:
379     memplugin_free(codec_name, TILER_1D_BUFFER);
380     return ((void *)codec_handle);
383 /*===============================================================*/
384 /** control               : Codec control call.
385  *
386  * @ param codec  [in]     : Codec Handle obtained in create() call.
387  * @ param id [in]            : Command id for XDM control operation.
388  * @ param dynParams [in] : Dynamic input parameters to Codec.
389  * @ param status [out]    : Codec returned status parameters.
390  * @ param codec_id [in]  : To differentiate between Encoder and Decoder codecs.
391  * @ return : Status of control() call is returned.
392  *                #XDM_EOK                  [0]   :  Success.
393  *                #XDM_EFAIL                [-1] :  Failure.
394  *                #IPC_FAIL                   [-2] : MmRpc Call failed.
395  *                #XDM_EUNSUPPORTED [-3] :  Unsupported request.
396  *                #OUT_OF_MEMORY       [-4] :  Out of Shared Memory.
397  */
398 static XDAS_Int32 control(void *codec, int id, void *dynParams, void *status, dce_codec_type codec_id)
400     MmRpc_FxnCtx        fxnCtx;
401     int32_t             fxnRet;
402     dce_error_status    eError = DCE_EOK;
404     _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
405     _ASSERT(dynParams != NULL, DCE_EINVALID_INPUT);
406     _ASSERT(status != NULL, DCE_EINVALID_INPUT);
408     /* Marshall function arguments into the send buffer */
409     Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_CONTROL, 5, 0, NULL);
410     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[0]), sizeof(int32_t), codec_id);
411     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[1]), sizeof(int32_t), (int32_t)codec);
412     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[2]), sizeof(int32_t), (int32_t)id);
413     Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[3]), GetSz(dynParams), P2H(dynParams),
414                                     sizeof(MemHeader), memplugin_share(dynParams));
415     Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[4]), GetSz(status), P2H(status),
416                                     sizeof(MemHeader), memplugin_share(status));
418     /* Invoke the Remote function through MmRpc */
419     eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
421     _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
423 EXIT:
424     return (fxnRet);
428 /*===============================================================*/
429 /** get_version        : Codec control call to get the codec version. This call has been made
430  *                                     separate from control call because it involves an additional version
431  *                                     buffer translation.
432  *
433  * @ param codec  [in]     : Codec Handle obtained in create() call.
434  * @ param id [in]            : Command id for XDM control operation.
435  * @ param dynParams [in] : Dynamic input parameters to Codec.
436  * @ param status [out]    : Codec returned status parameters.
437  * @ param codec_id [in]  : To differentiate between Encoder and Decoder codecs.
438  * @ return : Status of control() call is returned.
439  *                #XDM_EOK                  [0]   :  Success.
440  *                #XDM_EFAIL                [-1] :  Failure.
441  *                #IPC_FAIL                   [-2] : MmRpc Call failed.
442  *                #XDM_EUNSUPPORTED [-3] :  Unsupported request.
443  *                #OUT_OF_MEMORY       [-4] :  Out of Shared Memory.
444  */
445 static XDAS_Int32 get_version(void *codec, void *dynParams, void *status, dce_codec_type codec_id)
447     MmRpc_FxnCtx        fxnCtx;
448     MmRpc_Xlt           xltAry;
449     void             * *version_buf = NULL;
450     int32_t             fxnRet;
451     dce_error_status    eError = DCE_EOK;
453     _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
454     _ASSERT(dynParams != NULL, DCE_EINVALID_INPUT);
455     _ASSERT(status != NULL, DCE_EINVALID_INPUT);
457     if( codec_id == OMAP_DCE_VIDDEC3 ) {
458         version_buf = (void * *)(&(((IVIDDEC3_Status *)status)->data.buf));
459     } else if( codec_id == OMAP_DCE_VIDENC2 ) {
460         version_buf = (void * *)(&(((IVIDENC2_Status *)status)->data.buf));
461     }
462     _ASSERT(*version_buf != NULL, DCE_EINVALID_INPUT);
464     /* Marshall function arguments into the send buffer */
465     Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_GET_VERSION, 4, 1, &xltAry);
466     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[0]), sizeof(int32_t), codec_id);
467     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[1]), sizeof(int32_t), (int32_t)codec);
468     Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[2]), GetSz(dynParams), P2H(dynParams),
469                                     sizeof(MemHeader), memplugin_share(dynParams));
470     Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[3]), GetSz(status), P2H(status),
471                                     sizeof(MemHeader), memplugin_share(status));
473     /* Address Translation needed for buffer for version Info */
474     Fill_MmRpc_fxnCtx_Xlt_Array(fxnCtx.xltAry, 3, (int32_t)P2H(status), (int32_t)version_buf, memplugin_share(*version_buf));
476     /* Invoke the Remote function through MmRpc */
477     eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
479     _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
481 EXIT:
482     return (fxnRet);
485 typedef enum process_call_params {
486     CODEC_ID_INDEX = 0,
487     CODEC_HANDLE_INDEX,
488     INBUFS_INDEX,
489     OUTBUFS_INDEX,
490     INARGS_INDEX,
491     OUTARGS_INDEX
492 } process_call_params;
494 #define LUMA_BUF 0
495 #define CHROMA_BUF 1
496 /*===============================================================*/
497 /** process               : Encode/Decode process.
498  *
499  * @ param codec  [in]     : Codec Handle obtained in create() call.
500  * @ param inBufs [in]     : Input buffer details.
501  * @ param outBufs [in]    : Output buffer details.
502  * @ param inArgs [in]     : Input arguments.
503  * @ param outArgs [out]  : Output arguments.
504  * @ param codec_id [in]  : To differentiate between Encoder and Decoder codecs.
505  * @ return : Status of the process call.
506  *                #XDM_EOK                  [0]   :  Success.
507  *                #XDM_EFAIL                [-1] :  Failure.
508  *                #IPC_FAIL                   [-2] :  MmRpc Call failed.
509  *                #XDM_EUNSUPPORTED [-3] :  Unsupported request.
510  */
511 static XDAS_Int32 process(void *codec, void *inBufs, void *outBufs,
512                           void *inArgs, void *outArgs, dce_codec_type codec_id)
514     MmRpc_FxnCtx        fxnCtx;
515     MmRpc_Xlt           xltAry[MAX_TOTAl_BUF];
516     int                 fxnRet, count, total_count, numInBufs = 0, numOutBufs = 0;
517     dce_error_status    eError = DCE_EOK;
518     void             * *data_buf = NULL;
520     _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
521     _ASSERT(inBufs != NULL, DCE_EINVALID_INPUT);
522     _ASSERT(outBufs != NULL, DCE_EINVALID_INPUT);
523     _ASSERT(inArgs != NULL, DCE_EINVALID_INPUT);
524     _ASSERT(outArgs != NULL, DCE_EINVALID_INPUT);
526     if( codec_id == OMAP_DCE_VIDDEC3 ) {
527         numInBufs = ((XDM2_BufDesc *)inBufs)->numBufs;
528         numOutBufs = ((XDM2_BufDesc *)outBufs)->numBufs;
529     } else if( codec_id == OMAP_DCE_VIDENC2 ) {
530         numInBufs = ((IVIDEO2_BufDesc *)inBufs)->numPlanes;
531         numOutBufs = ((XDM2_BufDesc *)outBufs)->numBufs;
532     }
534     /* marshall function arguments into the send buffer                       */
535     /* Approach [2] as explained in "Notes" used for process               */
536     Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_PROCESS, 6, numInBufs + numOutBufs, xltAry);
537     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[CODEC_ID_INDEX]), sizeof(int32_t), codec_id);
538     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[CODEC_HANDLE_INDEX]), sizeof(int32_t), (int32_t)codec);
540     Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[INBUFS_INDEX]), GetSz(inBufs), P2H(inBufs),
541                                     sizeof(MemHeader), memplugin_share(inBufs));
542     Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[OUTBUFS_INDEX]), GetSz(outBufs), P2H(outBufs),
543                                     sizeof(MemHeader), memplugin_share(outBufs));
544     Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[INARGS_INDEX]), GetSz(inArgs), P2H(inArgs),
545                                     sizeof(MemHeader), memplugin_share(inArgs));
546     Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[OUTARGS_INDEX]), GetSz(outArgs), P2H(outArgs),
547                                     sizeof(MemHeader), memplugin_share(outArgs));
549     /* InBufs, OutBufs, InArgs, OutArgs buffer need translation but since they have been */
550     /* individually mentioned as fxnCtx Params, they need not be mentioned below again */
551     /* Input and Output Buffers have to be mentioned for translation                               */
552     for( count = 0, total_count = 0; count < numInBufs; count++, total_count++ ) {
553         if( codec_id == OMAP_DCE_VIDDEC3 ) {
554             data_buf = (void * *)(&(((XDM2_BufDesc *)inBufs)->descs[count].buf));
555             Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), INBUFS_INDEX, (int32_t)P2H(inBufs),
556                                         (int32_t)data_buf, (size_t)*data_buf);
557         } else if( codec_id == OMAP_DCE_VIDENC2 ) {
558             data_buf = (void * *)(&(((IVIDEO2_BufDesc *)inBufs)->planeDesc[count].buf));
559             Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), INBUFS_INDEX, (int32_t)P2H(inBufs),
560                                         (int32_t)data_buf, (size_t)*data_buf);
561         }
562     }
564     for( count = 0; count < numOutBufs; count++, total_count++ ) {
565         if(((XDM2_BufDesc *)outBufs)->descs[LUMA_BUF].buf != ((XDM2_BufDesc *)outBufs)->descs[CHROMA_BUF].buf ) {
566             /* MultiPlanar Buffers */
567             data_buf = (void * *)(&(((XDM2_BufDesc *)outBufs)->descs[count].buf));
568             Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), OUTBUFS_INDEX, (int32_t)P2H(outBufs),
569                                         (int32_t)data_buf, (size_t)*data_buf);
570         }
571 #if defined(BUILDOS_LINUX)
572         else {
573             /* SinglePlanar Buffers */
574             data_buf = (void * *)(&(((XDM2_BufDesc *)outBufs)->descs[count].buf));
575             Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), OUTBUFS_INDEX, (int32_t)P2H(outBufs),
576                                         (int32_t)data_buf, (size_t)*data_buf);
577             if( count == CHROMA_BUF ) {
578                 if(((XDM2_BufDesc *)outBufs)->descs[count].memType == XDM_MEMTYPE_RAW ||
579                    ((XDM2_BufDesc *)outBufs)->descs[count].memType == XDM_MEMTYPE_TILEDPAGE ) {
580                     *data_buf += ((XDM2_BufDesc *)outBufs)->descs[LUMA_BUF].bufSize.bytes;
581                 } else {
582                     *data_buf += ((XDM2_BufDesc *)outBufs)->descs[LUMA_BUF].bufSize.tileMem.width *
583                                  ((XDM2_BufDesc *)outBufs)->descs[LUMA_BUF].bufSize.tileMem.height;
584                 }
585             }
586         }
587 #endif
588     }
590     /* Invoke the Remote function through MmRpc */
591     eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
593     _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
595     eError = (dce_error_status)(fxnRet);
596 EXIT:
597     return (eError);
600 /*===============================================================*/
601 /** delete                : Delete Encode/Decode codec instance.
602  *
603  * @ param codec  [in]     : Codec Handle obtained in create() call.
604  * @ param codec_id [in]  : To differentiate between Encoder and Decoder codecs.
605  * @ return : NIL.
606  */
607 static void delete(void *codec, dce_codec_type codec_id)
609     MmRpc_FxnCtx        fxnCtx;
610     int32_t             fxnRet;
611     dce_error_status    eError = DCE_EOK;
613     _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
615     /* Marshall function arguments into the send buffer */
616     Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_DELETE, 2, 0, NULL);
617     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[0]), sizeof(int32_t), codec_id);
618     Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[1]), sizeof(int32_t), (int32_t)codec);
620     /* Invoke the Remote function through MmRpc */
621     eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
623     _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
625 EXIT:
626     return;
629 /*************** Deocder Codec Engine Functions ***********************/
630 VIDDEC3_Handle VIDDEC3_create(Engine_Handle engine, String name,
631                               VIDDEC3_Params *params)
633     VIDDEC3_Handle    codec;
635     DEBUG(">> engine=%p, name=%s, params=%p", engine, name, params);
636     codec = create(engine, name, params, OMAP_DCE_VIDDEC3);
637     DEBUG("<< codec=%p", codec);
638     return (codec);
641 XDAS_Int32 VIDDEC3_control(VIDDEC3_Handle codec, VIDDEC3_Cmd id,
642                            VIDDEC3_DynamicParams *dynParams, VIDDEC3_Status *status)
644     XDAS_Int32    ret;
646     DEBUG(">> codec=%p, id=%d, dynParams=%p, status=%p",
647           codec, id, dynParams, status);
648     if( id == XDM_GETVERSION ) {
649         ret = get_version(codec, dynParams, status, OMAP_DCE_VIDDEC3);
650     } else {
651         ret = control(codec, id, dynParams, status, OMAP_DCE_VIDDEC3);
652     }
653     DEBUG("<< ret=%d", ret);
654     return (ret);
657 XDAS_Int32 VIDDEC3_process(VIDDEC3_Handle codec,
658                            XDM2_BufDesc *inBufs, XDM2_BufDesc *outBufs,
659                            VIDDEC3_InArgs *inArgs, VIDDEC3_OutArgs *outArgs)
661     XDAS_Int32    ret;
663     DEBUG(">> codec=%p, inBufs=%p, outBufs=%p, inArgs=%p, outArgs=%p",
664           codec, inBufs, outBufs, inArgs, outArgs);
665     ret = process(codec, inBufs, outBufs, inArgs, outArgs, OMAP_DCE_VIDDEC3);
666     DEBUG("<< ret=%d", ret);
667     return (ret);
670 Void VIDDEC3_delete(VIDDEC3_Handle codec)
672     DEBUG(">> codec=%p", codec);
673     delete(codec, OMAP_DCE_VIDDEC3);
674     DEBUG("<<");
677 /*************** Enocder Codec Engine Functions ***********************/
678 VIDENC2_Handle VIDENC2_create(Engine_Handle engine, String name,
679                               VIDENC2_Params *params)
681     VIDENC2_Handle    codec;
683     DEBUG(">> engine=%p, name=%s, params=%p", engine, name, params);
684     codec = create(engine, name, params, OMAP_DCE_VIDENC2);
685     DEBUG("<< codec=%p", codec);
686     return (codec);
689 XDAS_Int32 VIDENC2_control(VIDENC2_Handle codec, VIDENC2_Cmd id,
690                            VIDENC2_DynamicParams *dynParams, VIDENC2_Status *status)
692     XDAS_Int32    ret;
694     DEBUG(">> codec=%p, id=%d, dynParams=%p, status=%p",
695           codec, id, dynParams, status);
696     ret = control(codec, id, dynParams, status, OMAP_DCE_VIDENC2);
697     DEBUG("<< ret=%d", ret);
698     return (ret);
701 XDAS_Int32 VIDENC2_process(VIDENC2_Handle codec,
702                            IVIDEO2_BufDesc *inBufs, XDM2_BufDesc *outBufs,
703                            VIDENC2_InArgs *inArgs, VIDENC2_OutArgs *outArgs)
705     XDAS_Int32    ret;
707     DEBUG(">> codec=%p, inBufs=%p, outBufs=%p, inArgs=%p, outArgs=%p",
708           codec, inBufs, outBufs, inArgs, outArgs);
709     ret = process(codec, inBufs, outBufs, inArgs, outArgs, OMAP_DCE_VIDENC2);
710     DEBUG("<< ret=%d", ret);
711     return (ret);
714 Void VIDENC2_delete(VIDENC2_Handle codec)
716     DEBUG(">> codec=%p", codec);
717     delete(codec, OMAP_DCE_VIDENC2);
718     DEBUG("<<");