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 #include <xdc/std.h>
76 /* IPC Headers */
77 #include <MmRpc.h>
79 /*DCE Headers */
80 #include "libdce.h"
81 #include "dce_rpc.h"
82 #include "dce_priv.h"
83 #include "memplugin.h"
86 /********************* GLOBALS ***********************/
87 /* Hande used for Remote Communication */
88 static MmRpc_Handle MmRpcHandle = NULL;
89 sem_t *dce_semaphore = NULL;
90 static int count = 0;
93 /****************** INLINE FUNCTIONS ********************/
95 static inline void Fill_MmRpc_fxnCtx(MmRpc_FxnCtx *fxnCtx, int fxn_id, int num_params, int num_xlts, MmRpc_Xlt *xltAry)
96 {
97 fxnCtx->fxn_id = fxn_id;
98 fxnCtx->num_params = num_params;
99 fxnCtx->num_xlts = num_xlts;
100 fxnCtx->xltAry = xltAry;
101 }
103 static inline void Fill_MmRpc_fxnCtx_OffPtr_Params(MmRpc_Param *mmrpc_params, int size, void *base, int offset, size_t handle)
104 {
105 mmrpc_params->type = MmRpc_ParamType_OffPtr;
106 mmrpc_params->param.offPtr.size = (size_t)size;
107 mmrpc_params->param.offPtr.base = (size_t)base;
108 mmrpc_params->param.offPtr.offset = (size_t)offset;
109 mmrpc_params->param.offPtr.handle = handle;
110 }
112 static inline void Fill_MmRpc_fxnCtx_Ptr_Params(MmRpc_Param *mmrpc_params, int size, void *addr, size_t handle)
113 {
114 mmrpc_params->type = MmRpc_ParamType_Ptr;
115 mmrpc_params->param.ptr.size = size;
116 mmrpc_params->param.ptr.addr = (size_t)addr;
117 mmrpc_params->param.ptr.handle = handle;
118 }
120 static inline void Fill_MmRpc_fxnCtx_Scalar_Params(MmRpc_Param *mmrpc_params, int size, int data)
121 {
122 mmrpc_params->type = MmRpc_ParamType_Scalar;
123 mmrpc_params->param.scalar.size = size;
124 mmrpc_params->param.scalar.data = (size_t)data;
125 }
127 static inline void Fill_MmRpc_fxnCtx_Xlt_Array(MmRpc_Xlt *mmrpc_xlt, int index, int32_t base, int32_t addr, size_t handle)
128 {
129 /* index : index of params filled in FxnCtx */
130 /* offset : calculated from address of index */
131 mmrpc_xlt->index = index;
132 mmrpc_xlt->offset = MmRpc_OFFSET(base, addr);
133 mmrpc_xlt->base = handle;
134 mmrpc_xlt->handle = handle;
135 }
137 /************************ FUNCTIONS **************************/
138 /* Interface for QNX for parameter buffer allocation */
139 /* These interfaces are implemented to maintain Backward Compatability */
140 void *dce_alloc(int sz)
141 {
142 return (memplugin_alloc(sz, 0, TILER_1D_BUFFER));
143 }
145 void dce_free(void *ptr)
146 {
147 memplugin_free(ptr, TILER_1D_BUFFER);
148 }
150 /*=====================================================================================*/
151 /** dce_ipc_init : Initialize MmRpc. This function is called within Engine_open().
152 *
153 * @ return : Error Status.
154 */
155 static int dce_ipc_init(void)
156 {
157 MmRpc_Params args;
158 dce_error_status eError = DCE_EOK;
160 printf(" >> dce_ipc_init\n");
162 count++;
163 /* Check if already Initialized */
164 _ASSERT(count == 1, DCE_EOK);
166 /* Create remote server insance */
167 MmRpc_Params_init(&args);
169 eError = MmRpc_create(DCE_DEVICE_NAME, &args, &MmRpcHandle);
171 _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CREATE_FAIL, count--);
173 printf("open(/dev/" DCE_DEVICE_NAME ") -> 0x%x\n", (int)MmRpcHandle);
175 EXIT:
176 return (eError);
177 }
179 /*=====================================================================================*/
180 /** dce_ipc_deinit : DeInitialize MmRpc. This function is called within
181 * Engine_close().
182 */
183 static void dce_ipc_deinit()
184 {
185 count--;
186 if( count > 0 ) {
187 goto EXIT;
188 }
190 if( MmRpcHandle != NULL ) {
191 MmRpc_delete(&MmRpcHandle);
192 }
193 MmRpcHandle = NULL;
195 EXIT:
196 return;
197 }
199 /*===============================================================*/
200 /** Engine_open : Open Codec Engine.
201 *
202 * @ param attrs [in] : Engine Attributes. This param is not passed to Remote core.
203 * @ param name [in] : Name of Encoder or Decoder codec.
204 * @ param ec [out] : Error returned by Codec Engine.
205 * @ return : Codec Engine Handle is returned to be used to create codec.
206 * In case of error, NULL is returned as Engine Handle.
207 */
208 Engine_Handle Engine_open(String name, Engine_Attrs *attrs, Engine_Error *ec)
209 {
210 MmRpc_FxnCtx fxnCtx;
211 dce_error_status eError = DCE_EOK;
212 dce_engine_open *engine_open_msg = NULL;
213 Engine_Attrs *engine_attrs = NULL;
214 Engine_Handle engine_handle = NULL;
216 _ASSERT(name != '\0', DCE_EINVALID_INPUT);
218 if( dce_semaphore == NULL ) {
219 _ASSERT((dce_semaphore = sem_open("/dce_semaphore", O_CREAT, S_IRWXU | S_IRWXO | S_IRWXG, 1)) != SEM_FAILED, DCE_ESEMAPHORE_FAIL);
220 }
221 /* Lock dce_ipc_init() and Engine_open() IPU call to prevent hang*/
222 _ASSERT(sem_wait(dce_semaphore) == DCE_EOK, DCE_ESEMAPHORE_FAIL);
224 /* Initialize IPC. In case of Error Deinitialize them */
225 _ASSERT_AND_EXECUTE(dce_ipc_init() == DCE_EOK, DCE_EIPC_CREATE_FAIL, dce_ipc_deinit());
227 printf(">> Engine_open Params::name = %s size = %d\n", name, strlen(name));
228 /* Allocate Shared memory for the engine_open rpc msg structure*/
229 /* Tiler Memory preferred in QNX */
230 engine_open_msg = memplugin_alloc(sizeof(dce_engine_open), 0, TILER_1D_BUFFER);
231 _ASSERT_AND_EXECUTE(engine_open_msg != NULL, DCE_EOUT_OF_MEMORY, engine_handle = NULL);
233 if( attrs ) {
234 engine_attrs = memplugin_alloc(sizeof(Engine_Attrs), 0, TILER_1D_BUFFER);
235 _ASSERT_AND_EXECUTE(engine_attrs != NULL, DCE_EOUT_OF_MEMORY, engine_handle = NULL);
236 *engine_attrs = *attrs;
237 }
238 /* Populating the msg structure with all the params */
239 /* Populating all params into a struct avoid individual address translations of name, ec */
240 strncpy(engine_open_msg->name, name, strlen(name));
241 engine_open_msg->engine_attrs = engine_attrs;
243 /* Marshall function arguments into the send buffer */
244 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_ENGINE_OPEN, 1, 0, NULL);
245 Fill_MmRpc_fxnCtx_OffPtr_Params(fxnCtx.params, GetSz(engine_open_msg), (void *)P2H(engine_open_msg),
246 sizeof(MemHeader), memplugin_share(engine_open_msg));
248 /* Invoke the Remote function through MmRpc */
249 eError = MmRpc_call(MmRpcHandle, &fxnCtx, (int32_t *)(&engine_handle));
251 /* In case of Error, the Application will get a NULL Engine Handle */
252 _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CALL_FAIL, engine_handle = NULL);
254 if( ec ) {
255 *ec = engine_open_msg->error_code;
256 }
258 EXIT:
259 /* Unlock dce_ipc_init() and Engine_open() IPU call */
260 _ASSERT(sem_post(dce_semaphore) == DCE_EOK, DCE_ESEMAPHORE_FAIL);
262 memplugin_free(engine_open_msg, TILER_1D_BUFFER);
263 if( engine_attrs ) {
264 memplugin_free(engine_attrs, TILER_1D_BUFFER);
265 }
266 return ((Engine_Handle)engine_handle);
267 }
269 /*===============================================================*/
270 /** Engine_close : Close Engine.
271 *
272 * @ param engine [in] : Engine Handle obtained in Engine_open() call.
273 */
274 Void Engine_close(Engine_Handle engine)
275 {
276 MmRpc_FxnCtx fxnCtx;
277 int32_t fxnRet;
278 dce_error_status eError = DCE_EOK;
280 _ASSERT(engine != NULL, DCE_EINVALID_INPUT);
282 /* Lock dce_ipc_deinit() and Engine_close() IPU call */
283 _ASSERT(sem_wait(dce_semaphore) == DCE_EOK, DCE_ESEMAPHORE_FAIL);
285 /* Marshall function arguments into the send buffer */
286 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_ENGINE_CLOSE, 1, 0, NULL);
287 Fill_MmRpc_fxnCtx_Scalar_Params(fxnCtx.params, sizeof(Engine_Handle), (int32_t)engine);
289 /* Invoke the Remote function through MmRpc */
290 eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
292 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
294 EXIT:
295 dce_ipc_deinit();
297 /* Unlock dce_ipc_deinit() and Engine_close() IPU call */
298 _ASSERT(sem_post(dce_semaphore) == DCE_EOK, DCE_ESEMAPHORE_FAIL);
299 sem_close(dce_semaphore);
301 return;
302 }
304 /*===============================================================*/
305 /** Functions create(), control(), get_version(), process(), delete() are common codec
306 * glue function signatures which are same for both encoder and decoder
307 */
308 /*===============================================================*/
309 /** create : Create Encoder/Decoder codec.
310 *
311 * @ param engine [in] : Engine Handle obtained in Engine_open() call.
312 * @ param name [in] : Name of Encoder or Decoder codec.
313 * @ param params [in] : Static parameters of codec.
314 * @ param codec_id [in] : To differentiate between Encoder and Decoder codecs.
315 * @ return : Codec Handle is returned to be used for control, process, delete calls.
316 * In case of error, NULL is returned.
317 */
318 static void *create(Engine_Handle engine, String name, void *params, dce_codec_type codec_id)
319 {
320 MmRpc_FxnCtx fxnCtx;
321 dce_error_status eError = DCE_EOK;
322 void *codec_handle = NULL;
323 char *codec_name = 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 memory for translating codec name to IPU */
330 codec_name = memplugin_alloc(MAX_NAME_LENGTH * sizeof(char), 0, TILER_1D_BUFFER);
331 _ASSERT_AND_EXECUTE(codec_name != NULL, DCE_EOUT_OF_MEMORY, codec_handle = NULL);
333 strncpy(codec_name, name, strlen(name));
335 /* Marshall function arguments into the send buffer */
336 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_CREATE, 4, 0, NULL);
337 Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[0]), sizeof(int32_t), codec_id);
338 Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[1]), sizeof(Engine_Handle), (int32_t)engine);
339 Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[2]), GetSz(codec_name), P2H(codec_name),
340 sizeof(MemHeader), memplugin_share(codec_name));
341 Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[3]), GetSz(params), P2H(params),
342 sizeof(MemHeader), memplugin_share(params));
343 /* Invoke the Remote function through MmRpc */
344 eError = MmRpc_call(MmRpcHandle, &fxnCtx, (int32_t *)(&codec_handle));
346 /* In case of Error, the Application will get a NULL Codec Handle */
347 _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CALL_FAIL, codec_handle = NULL);
349 EXIT:
350 memplugin_free(codec_name, TILER_1D_BUFFER);
351 return ((void *)codec_handle);
352 }
354 /*===============================================================*/
355 /** control : Codec control call.
356 *
357 * @ param codec [in] : Codec Handle obtained in create() call.
358 * @ param id [in] : Command id for XDM control operation.
359 * @ param dynParams [in] : Dynamic input parameters to Codec.
360 * @ param status [out] : Codec returned status parameters.
361 * @ param codec_id [in] : To differentiate between Encoder and Decoder codecs.
362 * @ return : Status of control() call is returned.
363 * #XDM_EOK [0] : Success.
364 * #XDM_EFAIL [-1] : Failure.
365 * #IPC_FAIL [-2] : MmRpc Call failed.
366 * #XDM_EUNSUPPORTED [-3] : Unsupported request.
367 * #OUT_OF_MEMORY [-4] : Out of Shared Memory.
368 */
369 static XDAS_Int32 control(void *codec, int id, void *dynParams, void *status, dce_codec_type codec_id)
370 {
371 MmRpc_FxnCtx fxnCtx;
372 int32_t fxnRet;
373 dce_error_status eError = DCE_EOK;
375 _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
376 _ASSERT(dynParams != NULL, DCE_EINVALID_INPUT);
377 _ASSERT(status != NULL, DCE_EINVALID_INPUT);
379 /* Marshall function arguments into the send buffer */
380 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_CONTROL, 5, 0, NULL);
381 Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[0]), sizeof(int32_t), codec_id);
382 Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[1]), sizeof(int32_t), (int32_t)codec);
383 Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[2]), sizeof(int32_t), (int32_t)id);
384 Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[3]), GetSz(dynParams), P2H(dynParams),
385 sizeof(MemHeader), memplugin_share(dynParams));
386 Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[4]), GetSz(status), P2H(status),
387 sizeof(MemHeader), memplugin_share(status));
389 /* Invoke the Remote function through MmRpc */
390 eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
392 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
394 EXIT:
395 return (fxnRet);
397 }
399 /*===============================================================*/
400 /** get_version : Codec control call to get the codec version. This call has been made
401 * separate from control call because it involves an additional version
402 * buffer translation.
403 *
404 * @ param codec [in] : Codec Handle obtained in create() call.
405 * @ param id [in] : Command id for XDM control operation.
406 * @ param dynParams [in] : Dynamic input parameters to Codec.
407 * @ param status [out] : Codec returned status parameters.
408 * @ param codec_id [in] : To differentiate between Encoder and Decoder codecs.
409 * @ return : Status of control() call is returned.
410 * #XDM_EOK [0] : Success.
411 * #XDM_EFAIL [-1] : Failure.
412 * #IPC_FAIL [-2] : MmRpc Call failed.
413 * #XDM_EUNSUPPORTED [-3] : Unsupported request.
414 * #OUT_OF_MEMORY [-4] : Out of Shared Memory.
415 */
416 static XDAS_Int32 get_version(void *codec, void *dynParams, void *status, dce_codec_type codec_id)
417 {
418 MmRpc_FxnCtx fxnCtx;
419 MmRpc_Xlt xltAry;
420 void * *version_buf = NULL;
421 int32_t fxnRet;
422 dce_error_status eError = DCE_EOK;
424 _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
425 _ASSERT(dynParams != NULL, DCE_EINVALID_INPUT);
426 _ASSERT(status != NULL, DCE_EINVALID_INPUT);
428 if( codec_id == OMAP_DCE_VIDDEC3 ) {
429 version_buf = (void * *)(&(((IVIDDEC3_Status *)status)->data.buf));
430 } else if( codec_id == OMAP_DCE_VIDENC2 ) {
431 version_buf = (void * *)(&(((IVIDENC2_Status *)status)->data.buf));
432 }
433 _ASSERT(*version_buf != NULL, DCE_EINVALID_INPUT);
435 /* Marshall function arguments into the send buffer */
436 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_GET_VERSION, 4, 1, &xltAry);
437 Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[0]), sizeof(int32_t), codec_id);
438 Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[1]), sizeof(int32_t), (int32_t)codec);
439 Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[2]), GetSz(dynParams), P2H(dynParams),
440 sizeof(MemHeader), memplugin_share(dynParams));
441 Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[3]), GetSz(status), P2H(status),
442 sizeof(MemHeader), memplugin_share(status));
444 /* Address Translation needed for buffer for version Info */
445 Fill_MmRpc_fxnCtx_Xlt_Array(fxnCtx.xltAry, 3, (int32_t)status, (int32_t)version_buf, memplugin_share(*version_buf));
447 /* Invoke the Remote function through MmRpc */
448 eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
450 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
452 EXIT:
453 return (fxnRet);
454 }
456 typedef enum process_call_params {
457 CODEC_ID_INDEX = 0,
458 CODEC_HANDLE_INDEX,
459 INBUFS_INDEX,
460 OUTBUFS_INDEX,
461 INARGS_INDEX,
462 OUTARGS_INDEX
463 } process_call_params;
465 #define LUMA_BUF 0
466 #define CHROMA_BUF 1
467 /*===============================================================*/
468 /** process : Encode/Decode process.
469 *
470 * @ param codec [in] : Codec Handle obtained in create() call.
471 * @ param inBufs [in] : Input buffer details.
472 * @ param outBufs [in] : Output buffer details.
473 * @ param inArgs [in] : Input arguments.
474 * @ param outArgs [out] : Output arguments.
475 * @ param codec_id [in] : To differentiate between Encoder and Decoder codecs.
476 * @ return : Status of the process call.
477 * #XDM_EOK [0] : Success.
478 * #XDM_EFAIL [-1] : Failure.
479 * #IPC_FAIL [-2] : MmRpc Call failed.
480 * #XDM_EUNSUPPORTED [-3] : Unsupported request.
481 */
482 static XDAS_Int32 process(void *codec, void *inBufs, void *outBufs,
483 void *inArgs, void *outArgs, dce_codec_type codec_id)
484 {
485 MmRpc_FxnCtx fxnCtx;
486 MmRpc_Xlt xltAry[MAX_TOTAl_BUF];
487 int fxnRet, count, total_count, numInBufs = 0, numOutBufs = 0;
488 dce_error_status eError = DCE_EOK;
489 void * *data_buf = NULL;
491 _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
492 _ASSERT(inBufs != NULL, DCE_EINVALID_INPUT);
493 _ASSERT(outBufs != NULL, DCE_EINVALID_INPUT);
494 _ASSERT(inArgs != NULL, DCE_EINVALID_INPUT);
495 _ASSERT(outArgs != NULL, DCE_EINVALID_INPUT);
497 if( codec_id == OMAP_DCE_VIDDEC3 ) {
498 numInBufs = ((XDM2_BufDesc *)inBufs)->numBufs;
499 numOutBufs = ((XDM2_BufDesc *)outBufs)->numBufs;
500 } else if( codec_id == OMAP_DCE_VIDENC2 ) {
501 numInBufs = ((IVIDEO2_BufDesc *)inBufs)->numPlanes;
502 numOutBufs = ((XDM2_BufDesc *)outBufs)->numBufs;
503 }
505 /* marshall function arguments into the send buffer */
506 /* Approach [2] as explained in "Notes" used for process */
507 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_PROCESS, 6, numInBufs + numOutBufs, xltAry);
508 Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[CODEC_ID_INDEX]), sizeof(int32_t), codec_id);
509 Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[CODEC_HANDLE_INDEX]), sizeof(int32_t), (int32_t)codec);
511 Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[INBUFS_INDEX]), GetSz(inBufs), P2H(inBufs),
512 sizeof(MemHeader), memplugin_share(inBufs));
513 Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[OUTBUFS_INDEX]), GetSz(outBufs), P2H(outBufs),
514 sizeof(MemHeader), memplugin_share(outBufs));
515 Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[INARGS_INDEX]), GetSz(inArgs), P2H(inArgs),
516 sizeof(MemHeader), memplugin_share(inArgs));
517 Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[OUTARGS_INDEX]), GetSz(outArgs), P2H(outArgs),
518 sizeof(MemHeader), memplugin_share(outArgs));
520 /* InBufs, OutBufs, InArgs, OutArgs buffer need translation but since they have been */
521 /* individually mentioned as fxnCtx Params, they need not be mentioned below again */
522 /* Input and Output Buffers have to be mentioned for translation */
523 for( count = 0, total_count = 0; count < numInBufs; count++, total_count++ ) {
524 if( codec_id == OMAP_DCE_VIDDEC3 ) {
525 data_buf = (void * *)(&(((XDM2_BufDesc *)inBufs)->descs[count].buf));
526 Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), INBUFS_INDEX, (int32_t)inBufs,
527 (int32_t)data_buf, (size_t)*data_buf);
528 } else if( codec_id == OMAP_DCE_VIDENC2 ) {
529 data_buf = (void * *)(&(((IVIDEO2_BufDesc *)inBufs)->planeDesc[count].buf));
530 Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), INBUFS_INDEX, (int32_t)inBufs,
531 (int32_t)data_buf, (size_t)*data_buf);
532 }
533 }
535 /* Output Buffers */
536 for( count = 0; count < numOutBufs; count++, total_count++ ) {
537 if(((XDM2_BufDesc *)outBufs)->descs[LUMA_BUF].buf != ((XDM2_BufDesc *)outBufs)->descs[CHROMA_BUF].buf ) {
538 /* Either Encode usecase or MultiPlanar Buffers for Decode usecase */
539 data_buf = (void * *)(&(((XDM2_BufDesc *)outBufs)->descs[count].buf));
540 Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), OUTBUFS_INDEX, (int32_t)outBufs,
541 (int32_t)data_buf, (size_t)*data_buf);
542 }
543 #if defined(BUILDOS_LINUX)
544 else {
545 /* SinglePlanar Buffers for Decode usecase*/
546 data_buf = (void * *)(&(((XDM2_BufDesc *)outBufs)->descs[count].buf));
547 Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), OUTBUFS_INDEX, (int32_t)outBufs,
548 (int32_t)data_buf, (size_t)*data_buf);
549 if( count == CHROMA_BUF ) {
550 if(((XDM2_BufDesc *)outBufs)->descs[count].memType == XDM_MEMTYPE_RAW ||
551 ((XDM2_BufDesc *)outBufs)->descs[count].memType == XDM_MEMTYPE_TILEDPAGE ) {
552 *data_buf += ((XDM2_BufDesc *)outBufs)->descs[LUMA_BUF].bufSize.bytes;
553 } else {
554 *data_buf += ((XDM2_BufDesc *)outBufs)->descs[LUMA_BUF].bufSize.tileMem.width *
555 ((XDM2_BufDesc *)outBufs)->descs[LUMA_BUF].bufSize.tileMem.height;
556 }
557 }
558 }
559 #endif
560 }
562 /* Invoke the Remote function through MmRpc */
563 eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
565 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
567 eError = (dce_error_status)(fxnRet);
568 EXIT:
569 return (eError);
570 }
572 /*===============================================================*/
573 /** delete : Delete Encode/Decode codec instance.
574 *
575 * @ param codec [in] : Codec Handle obtained in create() call.
576 * @ param codec_id [in] : To differentiate between Encoder and Decoder codecs.
577 * @ return : NIL.
578 */
579 static void delete(void *codec, dce_codec_type codec_id)
580 {
581 MmRpc_FxnCtx fxnCtx;
582 int32_t fxnRet;
583 dce_error_status eError = DCE_EOK;
585 _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
587 /* Marshall function arguments into the send buffer */
588 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_DELETE, 2, 0, NULL);
589 Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[0]), sizeof(int32_t), codec_id);
590 Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[1]), sizeof(int32_t), (int32_t)codec);
592 /* Invoke the Remote function through MmRpc */
593 eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet);
595 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
597 EXIT:
598 return;
599 }
601 /*************** Deocder Codec Engine Functions ***********************/
602 VIDDEC3_Handle VIDDEC3_create(Engine_Handle engine, String name,
603 VIDDEC3_Params *params)
604 {
605 VIDDEC3_Handle codec;
607 DEBUG(">> engine=%p, name=%s, params=%p", engine, name, params);
608 codec = create(engine, name, params, OMAP_DCE_VIDDEC3);
609 DEBUG("<< codec=%p", codec);
610 return (codec);
611 }
613 XDAS_Int32 VIDDEC3_control(VIDDEC3_Handle codec, VIDDEC3_Cmd id,
614 VIDDEC3_DynamicParams *dynParams, VIDDEC3_Status *status)
615 {
616 XDAS_Int32 ret;
618 DEBUG(">> codec=%p, id=%d, dynParams=%p, status=%p",
619 codec, id, dynParams, status);
620 if( id == XDM_GETVERSION ) {
621 ret = get_version(codec, dynParams, status, OMAP_DCE_VIDDEC3);
622 } else {
623 ret = control(codec, id, dynParams, status, OMAP_DCE_VIDDEC3);
624 }
625 DEBUG("<< ret=%d", ret);
626 return (ret);
627 }
629 XDAS_Int32 VIDDEC3_process(VIDDEC3_Handle codec,
630 XDM2_BufDesc *inBufs, XDM2_BufDesc *outBufs,
631 VIDDEC3_InArgs *inArgs, VIDDEC3_OutArgs *outArgs)
632 {
633 XDAS_Int32 ret;
635 DEBUG(">> codec=%p, inBufs=%p, outBufs=%p, inArgs=%p, outArgs=%p",
636 codec, inBufs, outBufs, inArgs, outArgs);
637 ret = process(codec, inBufs, outBufs, inArgs, outArgs, OMAP_DCE_VIDDEC3);
638 DEBUG("<< ret=%d", ret);
639 return (ret);
640 }
642 Void VIDDEC3_delete(VIDDEC3_Handle codec)
643 {
644 DEBUG(">> codec=%p", codec);
645 delete(codec, OMAP_DCE_VIDDEC3);
646 DEBUG("<<");
647 }
649 /*************** Enocder Codec Engine Functions ***********************/
650 VIDENC2_Handle VIDENC2_create(Engine_Handle engine, String name,
651 VIDENC2_Params *params)
652 {
653 VIDENC2_Handle codec;
655 DEBUG(">> engine=%p, name=%s, params=%p", engine, name, params);
656 codec = create(engine, name, params, OMAP_DCE_VIDENC2);
657 DEBUG("<< codec=%p", codec);
658 return (codec);
659 }
661 XDAS_Int32 VIDENC2_control(VIDENC2_Handle codec, VIDENC2_Cmd id,
662 VIDENC2_DynamicParams *dynParams, VIDENC2_Status *status)
663 {
664 XDAS_Int32 ret;
666 DEBUG(">> codec=%p, id=%d, dynParams=%p, status=%p",
667 codec, id, dynParams, status);
668 ret = control(codec, id, dynParams, status, OMAP_DCE_VIDENC2);
669 DEBUG("<< ret=%d", ret);
670 return (ret);
671 }
673 XDAS_Int32 VIDENC2_process(VIDENC2_Handle codec,
674 IVIDEO2_BufDesc *inBufs, XDM2_BufDesc *outBufs,
675 VIDENC2_InArgs *inArgs, VIDENC2_OutArgs *outArgs)
676 {
677 XDAS_Int32 ret;
679 DEBUG(">> codec=%p, inBufs=%p, outBufs=%p, inArgs=%p, outArgs=%p",
680 codec, inBufs, outBufs, inArgs, outArgs);
681 ret = process(codec, inBufs, outBufs, inArgs, outArgs, OMAP_DCE_VIDENC2);
682 DEBUG("<< ret=%d", ret);
683 return (ret);
684 }
686 Void VIDENC2_delete(VIDENC2_Handle codec)
687 {
688 DEBUG(">> codec=%p", codec);
689 delete(codec, OMAP_DCE_VIDENC2);
690 DEBUG("<<");
691 }