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