camera proxy: pass ion fd's instead of handles
[gstreamer-omap:domx.git] / omx_proxy_component / omx_camera / src / omx_proxy_camera.c
1 /*
2  * Copyright (c) 2010, 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  */
32
33 /**
34  *  @file  omx_proxy_camera.c
35  *         This file contains methods that provides the functionality for
36  *         the OpenMAX1.1 DOMX Framework Tunnel Proxy component.
37  ******************************************************************************
38  This is the proxy specific wrapper that passes the component name to the
39  generic proxy init() The proxy wrapper also does some runtime/static time
40  config on per proxy basis This is a thin wrapper that is called when
41  componentiit() of the proxy is called  static OMX_ERRORTYPE PROXY_Wrapper_init
42  (OMX_HANDLETYPE hComponent, OMX_PTR pAppData);
43  this layer gets called first whenever a proxy s get handle is called
44  ******************************************************************************
45  *  @path WTSD_DucatiMMSW\omx\omx_il_1_x\omx_proxy_component\src
46  *
47  *  @rev 1.0
48  */
49
50 /*==============================================================
51  *! Revision History
52  *! ============================
53  *! 19-August-2009 B Ravi Kiran ravi.kiran@ti.com: Initial Version
54  *================================================================*/
55
56 /******************************************************************
57  *   INCLUDE FILES
58  ******************************************************************/
59 #include <stdio.h>
60 #include <string.h>
61 #include <assert.h>
62 #include <dirent.h>
63 #include <stdio.h>
64 #include <string.h>
65 #include <pthread.h>
66 #include <sys/time.h>
67 #include <stdlib.h>
68 #include <errno.h>
69
70 #include <timm_osal_interfaces.h>
71 #include <OMX_TI_IVCommon.h>
72 #include <OMX_TI_Index.h>
73 #include "omx_proxy_common.h"
74 #include "timm_osal_mutex.h"
75
76 #ifdef USE_ION
77 #include <unistd.h>
78 #include <ion.h>
79 #include <sys/ioctl.h>
80 #include <sys/mman.h>
81 #include <sys/eventfd.h>
82 #include <fcntl.h>
83 #endif
84
85 #define COMPONENT_NAME "OMX.TI.DUCATI1.VIDEO.CAMERA"
86 /*Needs to be specific for every configuration wrapper*/
87
88 #undef LOG_TAG
89 #define LOG_TAG "CameraHAL"
90
91 #define DEFAULT_DCC 1
92
93 #define LINUX_PAGE_SIZE (4 * 1024)
94
95 #define _PROXY_OMX_INIT_PARAM(param,type) do {          \
96         TIMM_OSAL_Memset((param), 0, sizeof (type));    \
97         (param)->nSize = sizeof (type);                 \
98         (param)->nVersion.s.nVersionMajor = 1;          \
99         (param)->nVersion.s.nVersionMinor = 1;          \
100         } while(0)
101
102 /* VTC specific changes */
103 #define MAX_NUM_INTERNAL_BUFFERS 4
104 #define MAX_VTC_WIDTH 1920
105 #define MAX_VTC_HEIGHT 1080
106 #define BORDER_WIDTH 32
107 #define BORDER_HEIGHT 32
108 #define MAX_VTC_WIDTH_WITH_VNF (MAX_VTC_WIDTH + BORDER_WIDTH)
109 #define MAX_VTC_HEIGHT_WITH_VNF (MAX_VTC_HEIGHT + BORDER_HEIGHT)
110 OMX_PTR gCamIonHdl[MAX_NUM_INTERNAL_BUFFERS][2];
111
112 /* Tiler heap resservation specific */
113 #define OMAP_ION_HEAP_TILER_ALLOCATION_MASK (1<<4)
114 /* store handles for tracking and freeing */
115 OMX_PTR gComponentBufferAllocation[PROXY_MAXNUMOFPORTS][MAX_NUM_INTERNAL_BUFFERS];
116
117 /* Incase of multiple instance, making sure DCC is initialized only for
118    first instance */
119 static OMX_S16 numofInstance = 0;
120 int dcc_flag = 0;
121 TIMM_OSAL_PTR cam_mutex = NULL;
122
123 /* To store DCC buffer size */
124 OMX_S32 dccbuf_size = 0;
125
126 /* Ducati Mapped Addr  */
127 OMX_PTR DCC_Buff = NULL;
128
129 #ifdef USE_ION
130 OMX_PTR DCC_Buff_ptr = NULL;
131 int ion_fd;
132 int mmap_fd;
133 #endif
134
135 OMX_S32 read_DCCdir(OMX_PTR, OMX_STRING *, OMX_U16);
136 OMX_ERRORTYPE DCC_Init(OMX_HANDLETYPE);
137 OMX_ERRORTYPE send_DCCBufPtr(OMX_HANDLETYPE hComponent);
138 void DCC_DeInit();
139 OMX_ERRORTYPE PROXY_ComponentDeInit(OMX_HANDLETYPE);
140 OMX_ERRORTYPE __PROXY_SetConfig(OMX_HANDLETYPE, OMX_INDEXTYPE,
141                                                                 OMX_PTR, OMX_PTR);
142 OMX_ERRORTYPE __PROXY_GetConfig(OMX_HANDLETYPE, OMX_INDEXTYPE,
143                                                                 OMX_PTR, OMX_PTR);
144 OMX_ERRORTYPE __PROXY_SetParameter(OMX_IN OMX_HANDLETYPE, OMX_INDEXTYPE,
145                                                                         OMX_PTR, OMX_PTR, OMX_U32);
146 OMX_ERRORTYPE __PROXY_GetParameter(OMX_IN OMX_HANDLETYPE, OMX_INDEXTYPE,
147                                                                         OMX_PTR, OMX_PTR);
148 OMX_ERRORTYPE PROXY_SendCommand(OMX_HANDLETYPE, OMX_COMMANDTYPE,
149                                                                         OMX_U32,OMX_PTR);
150 OMX_ERRORTYPE CameraMaptoTilerDuc(OMX_TI_CONFIG_SHAREDBUFFER *, OMX_PTR *);
151 //COREID TARGET_CORE_ID = CORE_APPM3;
152
153 static OMX_ERRORTYPE ComponentPrivateDeInit(OMX_IN OMX_HANDLETYPE hComponent)
154 {
155         OMX_ERRORTYPE eError = OMX_ErrorNone;
156         TIMM_OSAL_ERRORTYPE eOsalError = TIMM_OSAL_ERR_NONE;
157         PROXY_COMPONENT_PRIVATE *pCompPrv;
158         OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent;
159         OMX_U32 i, j;
160
161         pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate;
162
163         if (dcc_flag)
164         {
165                 eOsalError =
166                     TIMM_OSAL_MutexObtain(cam_mutex, TIMM_OSAL_SUSPEND);
167                 if (eOsalError != TIMM_OSAL_ERR_NONE)
168                 {
169                         TIMM_OSAL_Error("Mutex Obtain failed");
170                 }
171
172                 numofInstance = numofInstance - 1;
173
174                 eOsalError = TIMM_OSAL_MutexRelease(cam_mutex);
175                 PROXY_assert(eOsalError == TIMM_OSAL_ERR_NONE,
176                     OMX_ErrorInsufficientResources, "Mutex release failed");
177         }
178         for(i=0; i < MAX_NUM_INTERNAL_BUFFERS; i++) {
179             if (gCamIonHdl[i][0] != NULL) {
180                 ion_free(pCompPrv->ion_fd, gCamIonHdl[i][0]);
181                 gCamIonHdl[i][0] = NULL;
182             }
183             if (gCamIonHdl[i][1] != NULL) {
184                 ion_free(pCompPrv->ion_fd, gCamIonHdl[i][1]);
185                 gCamIonHdl[i][1] = NULL;
186             }
187
188         }
189
190         for (i = 0; i < PROXY_MAXNUMOFPORTS; i++) {
191             for (j = 0; j < MAX_NUM_INTERNAL_BUFFERS; j++) {
192                 if (gComponentBufferAllocation[i][j]) {
193                     ion_free(pCompPrv->ion_fd, gComponentBufferAllocation[i][j]);
194                 }
195                 gComponentBufferAllocation[i][j] = NULL;
196             }
197         }
198
199         eError = PROXY_ComponentDeInit(hComponent);
200
201       EXIT:
202         return eError;
203 }
204
205 static OMX_ERRORTYPE Camera_SendCommand(OMX_IN OMX_HANDLETYPE hComponent,
206     OMX_IN OMX_COMMANDTYPE eCmd,
207     OMX_IN OMX_U32 nParam, OMX_IN OMX_PTR pCmdData)
208
209 {
210         OMX_ERRORTYPE eError = OMX_ErrorNone, eCompReturn;
211         RPC_OMX_ERRORTYPE eRPCError = RPC_OMX_ErrorNone;
212         PROXY_COMPONENT_PRIVATE *pCompPrv;
213         OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent;
214         static OMX_BOOL dcc_loaded = OMX_FALSE;
215
216         OMX_ERRORTYPE dcc_eError = OMX_ErrorNone;
217         TIMM_OSAL_ERRORTYPE eOsalError = TIMM_OSAL_ERR_NONE;
218         OMX_U32 i;
219
220         pCompPrv = (PROXY_COMPONENT_PRIVATE *) hComp->pComponentPrivate;
221
222         if ((eCmd == OMX_CommandStateSet) &&
223         (nParam == (OMX_STATETYPE) OMX_StateIdle))
224         {
225                 if (!dcc_loaded)
226                 {
227                         dcc_eError = DCC_Init(hComponent);
228                         if (dcc_eError != OMX_ErrorNone)
229                         {
230                                 DOMX_ERROR(" Error in DCC Init");
231                         }
232                         /* Configure Ducati to use DCC buffer from A9 side
233                          *ONLY* if DCC_Init is successful. */
234                         if (dcc_eError == OMX_ErrorNone)
235                         {
236                                 dcc_eError = send_DCCBufPtr(hComponent);
237                                 if (dcc_eError != OMX_ErrorNone)
238                                 {
239                                         DOMX_ERROR(" Error in Sending DCC Buf ptr");
240                                 }
241                                 DCC_DeInit();
242                         }
243                         dcc_loaded = OMX_TRUE;
244                 }
245         } else if (eCmd == OMX_CommandPortDisable) {
246             int i, j;
247             for (i = 0; i < MAX_NUM_INTERNAL_BUFFERS; i++) {
248                 for (j = 0; j < PROXY_MAXNUMOFPORTS; j++) {
249                     if (((j == nParam) || (nParam == OMX_ALL)) &&
250                          gComponentBufferAllocation[i][j])
251                     {
252                         ion_free(pCompPrv->ion_fd, gComponentBufferAllocation[i][j]);
253                         gComponentBufferAllocation[i][j] = NULL;
254                     }
255                 }
256             }
257
258         }
259
260
261         eError =
262         PROXY_SendCommand(hComponent,eCmd,nParam,pCmdData);
263
264
265 EXIT:
266
267    DOMX_EXIT("eError: %d", eError);
268    return eError;
269
270 }
271
272 /* ===========================================================================*/
273 /**
274  * @name CameraGetConfig()
275  * @brief For some specific indices, buffer allocated on A9 side
276  *        needs to be mapped and sent to Ducati.
277  * @param
278  * @return OMX_ErrorNone = Successful
279  */
280 /* ===========================================================================*/
281
282 static OMX_ERRORTYPE CameraGetConfig(OMX_IN OMX_HANDLETYPE
283     hComponent, OMX_IN OMX_INDEXTYPE nParamIndex,
284     OMX_INOUT OMX_PTR pComponentParameterStructure)
285 {
286         OMX_ERRORTYPE eError = OMX_ErrorNone;
287         OMX_TI_CONFIG_SHAREDBUFFER *pConfigSharedBuffer = NULL;
288         OMX_PTR pTempSharedBuff = NULL;
289         OMX_U32 status = 0;
290
291         switch (nParamIndex)
292         {
293         case OMX_TI_IndexConfigAAAskipBuffer:
294         case OMX_TI_IndexConfigCamCapabilities:
295         case OMX_TI_IndexConfigExifTags:
296         case OMX_TI_IndexConfigAlgoAreas:
297                 pConfigSharedBuffer =
298                         (OMX_TI_CONFIG_SHAREDBUFFER *) pComponentParameterStructure;
299
300                 pTempSharedBuff = pConfigSharedBuffer->pSharedBuff;
301
302                 // TODO(XXX): Cache API is not yet available. Client needs to
303                 // allocate tiler buffer directly and assign to pSharedBuff.
304                 // Ptr allocated by MemMgr_Alloc in uncacheable so there
305                 // would be no need to cache API
306
307                 eError = __PROXY_GetConfig(hComponent,
308                                                                 nParamIndex,
309                                                                 pConfigSharedBuffer,
310                                                                 &(pConfigSharedBuffer->pSharedBuff));
311
312                 PROXY_assert((eError == OMX_ErrorNone), eError,
313                     "Error in GetConfig");
314
315                 pConfigSharedBuffer->pSharedBuff = pTempSharedBuff;
316
317                 goto EXIT;
318                 break;
319         default:
320                 break;
321         }
322
323         return __PROXY_GetConfig(hComponent,
324                                                         nParamIndex,
325                                                         pComponentParameterStructure,
326                                                         NULL);
327
328  EXIT:
329         return eError;
330 }
331
332 /* ===========================================================================*/
333 /**
334  * @name CameraSetConfig()
335  * @brief For some specific indices, buffer allocated on A9 side needs to
336  *        be mapped and sent to Ducati.
337  * @param
338  * @return OMX_ErrorNone = Successful
339  */
340 /* ===========================================================================*/
341
342
343 static OMX_ERRORTYPE CameraSetConfig(OMX_IN OMX_HANDLETYPE
344     hComponent, OMX_IN OMX_INDEXTYPE nParamIndex,
345     OMX_INOUT OMX_PTR pComponentParameterStructure)
346 {
347         OMX_ERRORTYPE eError = OMX_ErrorNone;
348         OMX_TI_CONFIG_SHAREDBUFFER *pConfigSharedBuffer = NULL;
349         OMX_PTR pTempSharedBuff = NULL;
350         OMX_U32 status = 0;
351
352         switch (nParamIndex)
353         {
354         case OMX_TI_IndexConfigAAAskipBuffer:
355         case OMX_TI_IndexConfigCamCapabilities:
356         case OMX_TI_IndexConfigExifTags:
357         case OMX_TI_IndexConfigAlgoAreas:
358                 pConfigSharedBuffer =
359                         (OMX_TI_CONFIG_SHAREDBUFFER *)
360                         pComponentParameterStructure;
361
362                 pTempSharedBuff = pConfigSharedBuffer->pSharedBuff;
363
364                 // TODO(XXX): Cache API is not yet available. Client needs to
365                 // allocate tiler buffer directly and assign to pSharedBuff.
366                 // Ptr allocated by MemMgr_Alloc in uncacheable so there
367                 // would be no need to cache API
368
369                 eError = __PROXY_SetConfig(hComponent,
370                                                                 nParamIndex,
371                                                                 pConfigSharedBuffer,
372                                                                 &(pConfigSharedBuffer->pSharedBuff));
373
374                 PROXY_assert((eError == OMX_ErrorNone), eError,
375                     "Error in GetConfig");
376
377                 pConfigSharedBuffer->pSharedBuff = pTempSharedBuff;
378
379                 goto EXIT;
380                 break;
381         default:
382                 break;
383         }
384
385         return __PROXY_SetConfig(hComponent,
386                                                         nParamIndex,
387                                                         pComponentParameterStructure,
388                                                         NULL);
389
390  EXIT:
391         return eError;
392 }
393
394 static OMX_ERRORTYPE CameraSetParam(OMX_IN OMX_HANDLETYPE
395     hComponent, OMX_IN OMX_INDEXTYPE nParamIndex,
396     OMX_INOUT OMX_PTR pComponentParameterStructure)
397 {
398     OMX_ERRORTYPE eError = OMX_ErrorNone;
399     struct ion_handle *handle;
400     OMX_U32 i =0;
401     OMX_S32 ret = 0;
402     PROXY_COMPONENT_PRIVATE *pCompPrv;
403     OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *)hComponent;
404     OMX_U32 stride_Y = 0, stride_UV = 0;
405     OMX_TI_PARAM_VTCSLICE *pVtcConfig;// = (OMX_TI_PARAM_VTCSLICE *)pComponentParameterStructure;
406     OMX_TI_PARAM_COMPONENTBUFALLOCTYPE *bufferalloc = NULL;
407     int size = 0;
408     int fd1 = -1, fd2 = -1;
409
410     pCompPrv = (PROXY_COMPONENT_PRIVATE *)hComp->pComponentPrivate;
411     //fprintf(stdout, "DOMX: CameraSetParam: called!!!\n");
412     switch (nParamIndex)
413     {
414         case OMX_TI_IndexParamVtcSlice:
415             pVtcConfig = (OMX_TI_PARAM_VTCSLICE *)pComponentParameterStructure;
416             fprintf(stdout, "DOMX: CameraSetParam: OMX_TI_IndexParamVtcSlice is called!!!\n");
417             DOMX_ERROR("CameraSetParam Called for Vtc Slice index\n");
418
419             //fprintf(stdout, "CameraSetParam Called for Vtc Slice height = %d\n", ((OMX_TI_PARAM_VTCSLICE *)pComponentParameterStructure)->nSliceHeight);
420                     // MAX_NUM_INTERNAL_BUFFERS;
421
422                 for(i=0; i < MAX_NUM_INTERNAL_BUFFERS; i++) {
423                     pVtcConfig->nInternalBuffers = i;
424                     ret = ion_alloc_tiler(pCompPrv->ion_fd, MAX_VTC_WIDTH_WITH_VNF, MAX_VTC_HEIGHT_WITH_VNF, TILER_PIXEL_FMT_8BIT, OMAP_ION_HEAP_TILER_MASK, &handle, (size_t *)&stride_Y);
425                         if (ret < 0) {
426                                 DOMX_ERROR ("ION allocation failed - %s", strerror(errno));
427                                 goto EXIT;
428                         }
429
430                         ret = ion_share(pCompPrv->ion_fd, handle, &fd1);
431                         if (ret < 0) {
432                                 DOMX_ERROR("ION share failed");
433                                 ion_free(pCompPrv->ion_fd, handle);
434                                 goto EXIT;
435                         }
436
437                         pVtcConfig->IonBufhdl[0] = (OMX_PTR)(fd1);
438
439                     //fprintf(stdout, "DOMX: ION Buffer#%d: Y: 0x%x\n", i, pVtcConfig->IonBufhdl[0]);
440
441                         ret = ion_alloc_tiler(pCompPrv->ion_fd, MAX_VTC_WIDTH_WITH_VNF/2, MAX_VTC_HEIGHT_WITH_VNF/2, TILER_PIXEL_FMT_16BIT, OMAP_ION_HEAP_TILER_MASK, &handle, (size_t *)&stride_UV);
442                         if (ret < 0) {
443                                 DOMX_ERROR ("ION allocation failed - %s", strerror(errno));
444                                 goto EXIT;
445                         }
446
447                         ret = ion_share(pCompPrv->ion_fd, handle, &fd2);
448                         if (ret < 0) {
449                                 DOMX_ERROR("ION share failed");
450                                 ion_free(pCompPrv->ion_fd, handle);
451                                 goto EXIT;
452                         }
453
454                     pVtcConfig->IonBufhdl[1] = (OMX_PTR)(fd2);
455                     gCamIonHdl[i][0] = pVtcConfig->IonBufhdl[0];
456                     gCamIonHdl[i][1] = pVtcConfig->IonBufhdl[1];
457                     //fprintf(stdout, "DOMX: ION Buffer#%d: UV: 0x%x\n", i, pVtcConfig->IonBufhdl[1]);
458                     eError = __PROXY_SetParameter(hComponent,
459                                               OMX_TI_IndexParamVtcSlice,
460                                               pVtcConfig,
461                                         pVtcConfig->IonBufhdl, 2);
462                     close(fd1);
463                     close(fd2);
464                }
465                 goto EXIT;
466         case OMX_TI_IndexParamComponentBufferAllocation: {
467                 OMX_U32 port = 0, index = 0;
468                 int fd;
469                 bufferalloc = (OMX_TI_PARAM_COMPONENTBUFALLOCTYPE *)
470                         pComponentParameterStructure;
471
472                 port = bufferalloc->nPortIndex;
473                 index = bufferalloc->nIndex;
474
475                 size = (bufferalloc->nAllocWidth * bufferalloc->nAllocLines * 3) >> 1;
476                 ret = ion_alloc_tiler (pCompPrv->ion_fd, size, 1,
477                                        TILER_PIXEL_FMT_PAGE,
478                                        OMAP_ION_HEAP_TILER_ALLOCATION_MASK,
479                                        &handle, &stride_Y);
480                 if (ret < 0) {
481                         DOMX_ERROR ("ION allocation failed - %s", strerror(errno));
482                         goto EXIT;
483                 }
484
485                 ret = ion_share(pCompPrv->ion_fd, handle, &fd);
486                 if (ret < 0) {
487                         DOMX_ERROR("ION share failed");
488                         ion_free(pCompPrv->ion_fd, handle);
489                         goto EXIT;
490                 }
491
492                 bufferalloc->pBuf[0] = fd;
493                 eError = __PROXY_SetParameter(hComponent,
494                                               OMX_TI_IndexParamComponentBufferAllocation,
495                                               bufferalloc, &bufferalloc->pBuf[0], 1);
496                 if (eError != OMX_ErrorNone) {
497                    ion_free(pCompPrv->ion_fd, handle);
498                 } else {
499                    if (gComponentBufferAllocation[port][index]) {
500                        ion_free(pCompPrv->ion_fd, gComponentBufferAllocation[port][index]);
501                    }
502                    gComponentBufferAllocation[port][index] = handle;
503                 }
504                 close (fd);
505         }
506                 goto EXIT;
507                 break;
508         default:
509                  break;
510         }
511         eError = __PROXY_SetParameter(hComponent,
512                                                                 nParamIndex,
513                                                                 pComponentParameterStructure,
514                                                         NULL, 0);
515
516         if (eError != OMX_ErrorNone) {
517                 DOMX_ERROR(" CameraSetParam: Error in SetParam 0x%x", eError);
518         }
519 EXIT:
520     return eError;
521 }
522 OMX_ERRORTYPE OMX_ComponentInit(OMX_HANDLETYPE hComponent)
523 {
524         OMX_ERRORTYPE eError = OMX_ErrorNone;
525         OMX_ERRORTYPE dcc_eError = OMX_ErrorNone;
526         OMX_COMPONENTTYPE *pHandle = NULL;
527         PROXY_COMPONENT_PRIVATE *pComponentPrivate;
528         OMX_U32 i = 0, j = 0;
529         pHandle = (OMX_COMPONENTTYPE *) hComponent;
530         TIMM_OSAL_ERRORTYPE eOsalError = TIMM_OSAL_ERR_NONE;
531         DOMX_ENTER("_____________________INSIDE CAMERA PROXY"
532             "WRAPPER__________________________\n");
533         pHandle->pComponentPrivate = (PROXY_COMPONENT_PRIVATE *)
534             TIMM_OSAL_Malloc(sizeof(PROXY_COMPONENT_PRIVATE),
535             TIMM_OSAL_TRUE, 0, TIMMOSAL_MEM_SEGMENT_INT);
536
537         pComponentPrivate =
538             (PROXY_COMPONENT_PRIVATE *) pHandle->pComponentPrivate;
539         if (pHandle->pComponentPrivate == NULL)
540         {
541                 DOMX_ERROR(" ERROR IN ALLOCATING PROXY COMPONENT"
542                     "PRIVATE STRUCTURE");
543                 eError = OMX_ErrorInsufficientResources;
544                 goto EXIT;
545         }
546         TIMM_OSAL_Memset(pComponentPrivate, 0,
547                 sizeof(PROXY_COMPONENT_PRIVATE));
548
549         pComponentPrivate->cCompName =
550             TIMM_OSAL_Malloc(MAX_COMPONENT_NAME_LENGTH * sizeof(OMX_U8),
551             TIMM_OSAL_TRUE, 0, TIMMOSAL_MEM_SEGMENT_INT);
552         /*Copying component Name - this will be picked up in the proxy common */
553         assert(strlen(COMPONENT_NAME) + 1 < MAX_COMPONENT_NAME_LENGTH);
554         TIMM_OSAL_Memcpy(pComponentPrivate->cCompName, COMPONENT_NAME,
555             strlen(COMPONENT_NAME) + 1);
556
557         /*Calling Proxy Common Init() */
558         eError = OMX_ProxyCommonInit(hComponent);
559         if (eError != OMX_ErrorNone)
560         {
561                 DOMX_ERROR("\Error in Initializing Proxy");
562                 TIMM_OSAL_Free(pComponentPrivate->cCompName);
563                 TIMM_OSAL_Free(pComponentPrivate);
564                 goto EXIT;
565         }
566         for(i=0; i < MAX_NUM_INTERNAL_BUFFERS; i++) {
567             gCamIonHdl[i][0] = NULL;
568             gCamIonHdl[i][1] = NULL;
569         }
570
571         for (i = 0; i < PROXY_MAXNUMOFPORTS; i++) {
572             for (j = 0; j < MAX_NUM_INTERNAL_BUFFERS; j++) {
573                 gComponentBufferAllocation[i][j] = NULL;
574             }
575         }
576
577         pHandle->ComponentDeInit = ComponentPrivateDeInit;
578         pHandle->GetConfig = CameraGetConfig;
579         pHandle->SetConfig = CameraSetConfig;
580         pHandle->SendCommand = Camera_SendCommand;
581         pHandle->SetParameter = CameraSetParam;
582
583       EXIT:
584         return eError;
585 }
586
587 /* ===========================================================================*/
588 /**
589  * @name DCC_Init()
590  * @brief
591  * @param void
592  * @return OMX_ErrorNone = Successful
593  * @sa TBD
594  *
595  */
596 /* ===========================================================================*/
597 OMX_ERRORTYPE DCC_Init(OMX_HANDLETYPE hComponent)
598 {
599         OMX_TI_PARAM_DCCURIINFO param;
600         OMX_PTR ptempbuf;
601         OMX_U16 nIndex = 0;
602         OMX_ERRORTYPE eError = OMX_ErrorNone;
603 #ifdef USE_ION
604         int ret;
605 #endif
606
607         OMX_S32 status = 0;
608         OMX_STRING dcc_dir[200];
609         OMX_U16 i;
610         _PROXY_OMX_INIT_PARAM(&param, OMX_TI_PARAM_DCCURIINFO);
611
612         DOMX_ENTER("ENTER");
613         /* Read the the DCC URI info */
614         for (nIndex = 0; eError != OMX_ErrorNoMore; nIndex++)
615         {
616                 param.nIndex = nIndex;
617                 eError =
618                         OMX_GetParameter(hComponent,
619                         OMX_TI_IndexParamDccUriInfo, &param);
620
621                 PROXY_assert((eError == OMX_ErrorNone) ||
622                         (eError == OMX_ErrorNoMore), eError,
623                         "Error in GetParam for Dcc URI info");
624
625                 if (eError == OMX_ErrorNone)
626                 {
627                         DOMX_DEBUG("DCC URI's %s ", param.sDCCURI);
628                         dcc_dir[nIndex] =
629                                 TIMM_OSAL_Malloc(sizeof(OMX_U8) *
630                                 (strlen(DCC_PATH) + MAX_URI_LENGTH + 1),
631                                 TIMM_OSAL_TRUE, 0, TIMMOSAL_MEM_SEGMENT_INT);
632                         PROXY_assert(dcc_dir[nIndex] != NULL,
633                                 OMX_ErrorInsufficientResources, "Malloc failed");
634                         strcpy(dcc_dir[nIndex], DCC_PATH);
635                         strncat(dcc_dir[nIndex], (OMX_STRING) param.sDCCURI, MAX_URI_LENGTH);
636                         strcat(dcc_dir[nIndex], "/");
637                 }
638         }
639
640         /* setting  back errortype OMX_ErrorNone */
641         if (eError == OMX_ErrorNoMore)
642         {
643                 eError = OMX_ErrorNone;
644         }
645
646         dccbuf_size = read_DCCdir(NULL, dcc_dir, nIndex);
647
648     if(dccbuf_size <= 0)
649     {
650             DOMX_DEBUG("No DCC files found, switching back to default DCC");
651         return OMX_ErrorInsufficientResources;
652     }
653
654 #ifdef USE_ION
655         ion_fd = ion_open();
656         if(ion_fd == 0)
657         {
658                 DOMX_ERROR("ion_open failed!!!");
659                 return OMX_ErrorInsufficientResources;
660         }
661         dccbuf_size = (dccbuf_size + LINUX_PAGE_SIZE -1) & ~(LINUX_PAGE_SIZE - 1);
662         ret = ion_alloc(ion_fd, dccbuf_size, 0x1000, 1 << ION_HEAP_TYPE_CARVEOUT,
663                 (struct ion_handle **)&DCC_Buff);
664         if (ret)
665                         return OMX_ErrorInsufficientResources;
666
667         if (ion_map(ion_fd, DCC_Buff, dccbuf_size, PROT_READ | PROT_WRITE, MAP_SHARED, 0,
668                    (unsigned char **)&DCC_Buff_ptr, &mmap_fd) < 0)
669         {
670                 DOMX_ERROR("userspace mapping of ION buffers returned error");
671                 return OMX_ErrorInsufficientResources;
672         }
673         ptempbuf = DCC_Buff_ptr;
674 #endif
675         dccbuf_size = read_DCCdir(ptempbuf, dcc_dir, nIndex);
676
677         PROXY_assert(dccbuf_size > 0, OMX_ErrorInsufficientResources,
678                 "ERROR in copy DCC files into buffer");
679
680  EXIT:
681         for (i = 0; i < nIndex - 1; i++)
682         {
683                         TIMM_OSAL_Free(dcc_dir[i]);
684         }
685
686         return eError;
687
688 }
689
690 /* ===========================================================================*/
691 /**
692  * @name send_DCCBufPtr()
693  * @brief : Sending the DCC uri buff addr to ducati
694  * @param void
695  * @return return = 0 is successful
696  * @sa TBD
697  *
698  */
699 /* ===========================================================================*/
700
701 OMX_ERRORTYPE send_DCCBufPtr(OMX_HANDLETYPE hComponent)
702 {
703         OMX_TI_CONFIG_SHAREDBUFFER uribufparam;
704         OMX_ERRORTYPE eError = OMX_ErrorNone;
705
706         _PROXY_OMX_INIT_PARAM(&uribufparam, OMX_TI_CONFIG_SHAREDBUFFER);
707         uribufparam.nPortIndex = OMX_ALL;
708
709         DOMX_ENTER("ENTER");
710
711         uribufparam.nSharedBuffSize = dccbuf_size;
712 #ifdef USE_ION
713         uribufparam.pSharedBuff = (OMX_PTR) mmap_fd;
714 #else
715         uribufparam.pSharedBuff = (OMX_PTR) DCC_Buff;
716 #endif
717
718         DOMX_DEBUG("SYSLINK MAPPED ADDR:  0x%x sizeof buffer %d",
719                 uribufparam.pSharedBuff, uribufparam.nSharedBuffSize);
720
721         eError = __PROXY_SetParameter(hComponent,
722                                                                 OMX_TI_IndexParamDccUriBuffer,
723                                                                 &uribufparam,
724                                                                 &(uribufparam.pSharedBuff), 1);
725
726         if (eError != OMX_ErrorNone) {
727                 DOMX_ERROR(" Error in SetParam for DCC Uri Buffer 0x%x", eError);
728         }
729
730         DOMX_EXIT("EXIT");
731         return eError;
732 }
733
734 /* ===========================================================================*/
735 /**
736  * @name read_DCCdir()
737  * @brief : copies all the dcc profiles into the allocated 1D-Tiler buffer
738  *          and returns the size of the buffer.
739  * @param void : OMX_PTR is null then returns the size of the DCC directory
740  * @return return = size of the DCC directory or error in case of any failures
741  *                  in file read or open
742  * @sa TBD
743  *
744  */
745 /* ===========================================================================*/
746 OMX_S32 read_DCCdir(OMX_PTR buffer, OMX_STRING * dir_path, OMX_U16 numofURI)
747 {
748         FILE *pFile;
749         OMX_S32 lSize;
750         OMX_S32 dcc_buf_size = 0;
751         size_t result;
752         OMX_STRING filename;
753         char temp[200];
754         OMX_STRING dotdot = "..";
755         DIR *d;
756         struct dirent *dir;
757         OMX_U16 i = 0;
758         OMX_S32 ret = 0;
759
760         DOMX_ENTER("ENTER");
761         for (i = 0; i < numofURI - 1; i++)
762         {
763                 d = opendir(dir_path[i]);
764                 if (d)
765                 {
766                         /* read each filename */
767                         while ((dir = readdir(d)) != NULL)
768                         {
769                                 filename = dir->d_name;
770                                 strcpy(temp, dir_path[i]);
771                                 strcat(temp, filename);
772                                 if ((*filename != *dotdot))
773                                 {
774                                         DOMX_DEBUG
775                                             ("\n\t DCC Profiles copying into buffer => %s mpu_addr: %p",
776                                             temp, buffer);
777                                         pFile = fopen(temp, "rb");
778                                         if (pFile == NULL)
779                                         {
780                                                 DOMX_ERROR("File open error");
781                                                 ret = -1;
782                                         } else
783                                         {
784                                                 fseek(pFile, 0, SEEK_END);
785                                                 lSize = ftell(pFile);
786                                                 rewind(pFile);
787                                                 /* buffer is not NULL then copy all the DCC profiles into buffer
788                                                    else return the size of the DCC directory */
789                                                 if (buffer)
790                                                 {
791                                                         // copy file into the buffer:
792                                                         result =
793                                                             fread(buffer, 1,
794                                                             lSize, pFile);
795                                                         if (result != (size_t) lSize)
796                                                         {
797                                                                 DOMX_ERROR
798                                                                     ("fread: Reading error");
799                                                                 ret = -1;
800                                                         }
801                                                         buffer =
802                                                             buffer + lSize;
803                                                 }
804                                                 /* getting the size of the total dcc files available in FS */
805                                                 dcc_buf_size =
806                                                     dcc_buf_size + lSize;
807                                                 // terminate
808                                                 fclose(pFile);
809                                         }
810                                 }
811                         }
812                         closedir(d);
813                 }
814         }
815         if (ret == 0)
816                 ret = dcc_buf_size;
817
818         DOMX_EXIT("return %d", ret);
819         return ret;
820 }
821
822 /* ===========================================================================*/
823 /**
824  * @name DCC_Deinit()
825  * @brief
826  * @param void
827  * @return void
828  * @sa TBD
829  *
830  */
831 /* ===========================================================================*/
832 void DCC_DeInit()
833 {
834         DOMX_ENTER("ENTER");
835
836         if (DCC_Buff)
837         {
838 #ifdef USE_ION
839                 munmap(DCC_Buff_ptr, dccbuf_size);
840                 close(mmap_fd);
841                 ion_free(ion_fd, DCC_Buff);
842                 ion_close(ion_fd);
843                 DCC_Buff = NULL;
844 #endif
845         }
846
847         DOMX_EXIT("EXIT");
848 }
849
850
851
852 /*===============================================================*/
853 /** @fn Cam_Setup : This function is called when the the OMX Camera library is
854  *                  loaded. It creates a mutex, which is used during DCC_Init()
855  */
856 /*===============================================================*/
857 void __attribute__ ((constructor)) Cam_Setup(void)
858 {
859         TIMM_OSAL_ERRORTYPE eError = TIMM_OSAL_ERR_NONE;
860
861         eError = TIMM_OSAL_MutexCreate(&cam_mutex);
862         if (eError != TIMM_OSAL_ERR_NONE)
863         {
864                 TIMM_OSAL_Error("Creation of default mutex failed");
865         }
866 }
867
868
869 /*===============================================================*/
870 /** @fn Cam_Destroy : This function is called when the the OMX Camera library is
871  *                    unloaded. It destroys the mutex which was created by
872  *                    Core_Setup().
873  *
874  */
875 /*===============================================================*/
876 void __attribute__ ((destructor)) Cam_Destroy(void)
877 {
878         TIMM_OSAL_ERRORTYPE eError = TIMM_OSAL_ERR_NONE;
879
880         eError = TIMM_OSAL_MutexDelete(cam_mutex);
881         if (eError != TIMM_OSAL_ERR_NONE)
882         {
883                 TIMM_OSAL_Error("Destruction of default mutex failed");
884         }
885 }