/*! Allocates and Initilizes the mutual exclusion object.
 *
 *	@param [out] sync_obj
 *		The mutex object
 *	@return efsl_osal_return_type_t
 *		E_FSL_OSAL_SUCCESS if success
 *		E_FSL_OSAL_UNAVAILABLE if mutex not available
 */
efsl_osal_return_type_t fsl_osal_mutex_init(fsl_osal_mutex *sync_obj, fsl_osal_mutex_type type)
{
     pthread_mutexattr_t attr;
     
 	*sync_obj = (pthread_mutex_t *)fsl_osal_malloc_new(sizeof(pthread_mutex_t));
 	if(*sync_obj == NULL)
 	{
 		LOG_ERROR("\n malloc of mutex object failed.");
 		return E_FSL_OSAL_UNAVAILABLE;
 	}
    
    pthread_mutexattr_init(&attr);     
    switch(type)
    {
        case fsl_osal_mutex_normal:
            pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_NORMAL);
            break;
        case fsl_osal_mutex_recursive:
            pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE_NP);
            break;
        case fsl_osal_mutex_errorcheck:
            pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_ERRORCHECK_NP);
            break;
        default:
            pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_NORMAL);
            break;
    }
    
 	pthread_mutex_init((pthread_mutex_t *)(*sync_obj), &attr);

 	return E_FSL_OSAL_SUCCESS;
}
OMX_ERRORTYPE FileWrite::SetParameter(
        OMX_INDEXTYPE nParamIndex, 
        OMX_PTR pComponentParameterStructure)
{
    OMX_ERRORTYPE ret = OMX_ErrorNone;

    switch (nParamIndex) {
		case OMX_IndexParamCustomContentPipe:
			hPipe =(CP_PIPETYPE* ) (((OMX_PARAM_CONTENTPIPETYPE *)pComponentParameterStructure)->hPipe);
			break;
		case OMX_IndexParamContentURI:
		{
			OMX_PARAM_CONTENTURITYPE * pContentURI = (OMX_PARAM_CONTENTURITYPE *)pComponentParameterStructure;
			OMX_S32 nMediaNameLen = strlen((const char *)&(pContentURI->contentURI)) + 1;
				
            pMediaName = (OMX_S8 *)fsl_osal_malloc_new(nMediaNameLen);
            if (!pMediaName)
            {
                ret = OMX_ErrorInsufficientResources;
                break;
            }
			strcpy((char *)pMediaName, (const char *)&(pContentURI->contentURI));

			break;
		}
        default:
            ret = OMX_ErrorUnsupportedIndex;
            break;
    }

    return ret;
}
OMX_ERRORTYPE load_component(HTEST *hTest)
{
	OMX_ERRORTYPE ret = OMX_ErrorNone;
	OMX_HANDLETYPE hComponent = NULL;
	OMX_PARAM_PORTDEFINITIONTYPE sPortDef;
	OMX_U32 i;

	ret = OMX_GetHandle(&hComponent, hTest->name, hTest, &gCallBacks);
	if(ret != OMX_ErrorNone)
	{
		printf("Load component %s failed.\n", hTest->name);
		return ret;
	}

	hTest->hComponent = (OMX_COMPONENTTYPE*)hComponent;
	hTest->nPorts = get_component_ports(hComponent);
	OMX_INIT_STRUCT(&sPortDef, OMX_PARAM_PORTDEFINITIONTYPE);
	for(i=0; i<hTest->nPorts; i++)
	{
		sPortDef.nPortIndex = i;
		OMX_GetParameter(hComponent, OMX_IndexParamPortDefinition, &sPortDef);
		if (sPortDef.eDomain == OMX_PortDomainAudio)
			hTest->nAudioTrackNum = i;
		if (sPortDef.eDomain == OMX_PortDomainVideo)
			hTest->nVideoTrackNum = i;

		hTest->PortDir[i] = sPortDef.eDir;
		if(hTest->PortDir[i] == OMX_DirInput)
			hTest->bAllocater[i] = OMX_FALSE;
		if(hTest->PortDir[i] == OMX_DirOutput)
			hTest->bAllocater[i] = OMX_TRUE;
	}
	OMX_PARAM_CONTENTURITYPE *content = NULL;

	content =(OMX_PARAM_CONTENTURITYPE *) fsl_osal_malloc_new(sizeof(OMX_PARAM_CONTENTURITYPE) + 1024);
	if (!content)
		return OMX_ErrorInsufficientResources;

	fsl_osal_memset(content, 0 , sizeof(OMX_PARAM_CONTENTURITYPE)+1024);
	OMX_INIT_STRUCT(content,OMX_PARAM_CONTENTURITYPE);
	char* uri = (char*)&(content->contentURI);
	fsl_osal_memcpy(uri, hTest->media_name, strlen(hTest->media_name)+1);

	ret = OMX_SetParameter(hTest->hComponent,OMX_IndexParamContentURI,content);
	if (ret != OMX_ErrorNone)
	{
		OMX_FreeHandle(hTest->hComponent);
		hTest->hComponent = NULL;
		return ret;
	}




	fsl_osal_thread_create(&hTest->pThreadId, NULL, process_thread, hTest);

	return OMX_ErrorNone;
}
static Mem_Desc * new_Mem_Desc()
{
	Mem_Desc * newbuffer = NULL;
	if (tm->freelist)
	{
		newbuffer = tm->freelist;
		tm->freelist = newbuffer->next;
		return newbuffer;
	}
	if (tm->allocatednum)
		tm->allocatednum <<=1;
	else
		tm->allocatednum = 1000;
	if ((newbuffer = (Mem_Desc *)fsl_osal_malloc_new(sizeof(Mem_Desc)*tm->allocatednum)) != NULL)
	{
		Mem_Desc *oldhead, *nb;
		fsl_osal_u32 i = 0;

		oldhead = tm->head;
		nb = newbuffer;
		tm->freelist = tm->head = tm->tail = NULL;
		for (i=0; i<(tm->allocatednum-1); i++)
		{
			if (oldhead)
			{
				COPYMEMORYDESC(nb, oldhead);
				nb->next = NULL;
				if (tm->tail)
				{
					(tm->tail)->next = nb;
					tm->tail = nb;
				}
				else
				{
					tm->head = tm->tail = nb;
				}
				oldhead = oldhead->next;
			}
			else
			{
				nb->next = tm->freelist;
				tm->freelist = nb;
			}
			nb++;
		}
		if (tm->allocatedbuffer)
		{
			fsl_osal_dealloc(tm->allocatedbuffer);
		}
		tm->allocatedbuffer = newbuffer;
		return nb;
	}
	else
	{
		return newbuffer;
	}
}
/*! Allocates and Initilizes the semaphore object.
 *
 *	@param [out] sem_obj
 *		The semaphore object
 *	@param [in] pshared
 *		This argument indicates whether semaphore is shared across
 *		processes.
 *	@param [in] value
 *		The value indicates the initial value of the
 *		count associated with the semaphore.
 *	@return efsl_osal_return_type_t
 *		E_FSL_OSAL_SUCCESS if success
 *		E_FSL_OSAL_UNAVAILABLE if semaphore not available
 *		E_FSL_OSAL_FAILURE if semaphore initialisation is unsuccessful
 */
efsl_osal_return_type_t fsl_osal_sem_init(fsl_osal_sem *sem_obj,
        fsl_osal_s32 pshared,
        fsl_osal_u32 value)
{
	*sem_obj = (sem_t *)fsl_osal_malloc_new(sizeof(sem_t));
	if(*sem_obj == NULL)
	{
		LOG_ERROR("\n Creation of semaphore failed.");
		return E_FSL_OSAL_UNAVAILABLE;
	}
	if(sem_init((sem_t *)(*sem_obj), pshared, value) != 0)
		return E_FSL_OSAL_FAILURE;

	return E_FSL_OSAL_SUCCESS;
}
OMX_ERRORTYPE load_component(HTEST *hTest, OMX_U32 idx)
{
	OMX_ERRORTYPE ret = OMX_ErrorNone;
	OMX_COMPONENTTYPE *hComponent = NULL;
	OMX_COMPONENTINITTYPE pInit = NULL;
	OMX_STRING cError;

	hTest->pLibHandle[idx] = dlopen(hTest->lib_name[idx], RTLD_NOW);
	if(hTest->pLibHandle[idx] == NULL)
	{
		cError = dlerror();
		printf("%s\n", cError);
		return OMX_ErrorInvalidComponentName;
	}

	pInit = (OMX_COMPONENTINITTYPE)dlsym(hTest->pLibHandle[idx], hTest->itf_name[idx]);
	if(pInit == NULL)
	{
		cError = dlerror();
		printf("%s\n", cError);
		return OMX_ErrorInvalidComponent;
	}

	hComponent = (OMX_COMPONENTTYPE*)fsl_osal_malloc_new(sizeof(OMX_COMPONENTTYPE));
	if(hComponent == NULL)
	{
		printf("Failed to allocate memory for hComponent.\n");
		return OMX_ErrorInsufficientResources;
	}
	OMX_INIT_STRUCT(hComponent, OMX_COMPONENTTYPE);

	ret = pInit((OMX_HANDLETYPE)(hComponent));
	if(ret != OMX_ErrorNone)
	{
		printf("Load component failed.\n");
		return OMX_ErrorInvalidComponentName;
	}

	hComponent->SetCallbacks(hComponent, &gCallBacks, hTest);
	hTest->component[idx].hComponent = hComponent;


	return OMX_ErrorNone;
}
HTEST * create_test(
    OMX_STRING component,
    OMX_STRING in_file)
{
	HTEST *hTest = NULL;

	hTest = (HTEST*)fsl_osal_malloc_new(sizeof(HTEST));
	if(hTest == NULL)
	{
		printf("Failed to allocate memory for test handle.\n");
		return 0;
	}
	fsl_osal_memset(hTest, 0, sizeof(HTEST));

	hTest->name = component;

	hTest->pMsgQ = FSL_NEW(Queue, ());
	if(hTest->pMsgQ == NULL)
	{
		printf("Create message queue failed.\n");
		return 0;
	}
	hTest->pMsgQ->Create(128, sizeof(MSG), E_FSL_OSAL_TRUE);

	MakeDumpFileName(in_file,hTest->dump_file_path0,0);
	MakeDumpFileName(in_file,hTest->dump_file_path1,1);

	hTest->pOutFile0 = fopen(hTest->dump_file_path0, "wb");
	if(hTest->pOutFile0 == NULL)
	{
		printf("Failed to open file: %s\n", hTest->dump_file_path0);
		return 0;
	}
	hTest->pOutFile1 = fopen(hTest->dump_file_path1, "wb");
	if(hTest->pOutFile1 == NULL)
	{
		printf("Failed to open file: %s\n", hTest->dump_file_path1);
		return 0;
	}

	fsl_osal_sem_init(&(hTest->sParserFormatSem), 0, 0);
	return hTest;
}
int main(int argc, char *argv[])
{
	HTEST *hTest = NULL;

	if(argc < 3)
	{
		printf("Usage: ./bin <in_file> <out_file>\n");
		return 0;
	}

	hTest = (HTEST*)fsl_osal_malloc_new(sizeof(HTEST));
	if(hTest == NULL)
	{
		printf("Failed to allocate memory for test handle.\n");
		return 0;
	}
	fsl_osal_memset(hTest, 0, sizeof(HTEST));

	hTest->nComponents = 2;

	hTest->lib_name[0] = "../lib/lib_omx_template_arm11_elinux.so";
	hTest->itf_name[0] = "TemplateInit";
	hTest->component[0].nPorts = 2;
	hTest->component[0].PortDir[0] = OMX_DirInput;
	hTest->component[0].bAllocater[0] = OMX_TRUE;
	hTest->component[0].PortDir[1] = OMX_DirOutput;
	hTest->component[0].bAllocater[1] = OMX_TRUE;

	hTest->lib_name[1] = "../lib/lib_omx_template_arm11_elinux.so";
	hTest->itf_name[1] = "TemplateInit";
	hTest->component[1].nPorts = 2;
	hTest->component[1].PortDir[0] = OMX_DirInput;
	hTest->component[1].bAllocater[0] = OMX_TRUE;
	hTest->component[1].PortDir[1] = OMX_DirOutput;
	hTest->component[1].bAllocater[1] = OMX_TRUE;

	hTest->pMsgQ = FSL_NEW(Queue, ());
	if(hTest->pMsgQ == NULL)
	{
		printf("Create message queue failed.\n");
		return 0;
	}
	hTest->pMsgQ->Create(128, sizeof(MSG), E_FSL_OSAL_TRUE);

	hTest->pInFile = fopen(argv[1], "rb");
	if(hTest->pInFile == NULL)
	{
		printf("Failed to open file: %s\n", argv[1]);
		return 0;
	}

	hTest->pOutFile = fopen(argv[2], "wb");
	if(hTest->pOutFile == NULL)
	{
		printf("Failed to open file: %s\n", argv[2]);
		return 0;
	}

	cmd_process(hTest);

	return 1;
}
fsl_osal_ptr dbg_malloc(fsl_osal_u32 size, fsl_osal_char * desc, fsl_osal_s32 line)
{
	Mem_Desc * bt;
	fsl_osal_ptr buf = NULL;

#ifdef MEM_CHECK_BOARDER
	fsl_osal_ptr ptr = NULL;
	fsl_osal_s32 size1 = size;

	size += PRE_SIZE + AFT_SIZE;
#endif

	if ((buf = fsl_osal_malloc_new(size)) && (bt = new_Mem_Desc()))
	{
		tm->age++;
		tm->size+=size;
		if (tm->size>tm->maxsize)
		{
			tm->maxsize = tm->size;
			//printf("%s: mem exceed %ld bytes\n", tm->shortname, tm->maxsize);
		}

#ifdef MEM_CHECK_BOARDER
		fsl_osal_memset(buf, MAGICNUMBER, PRE_SIZE);
		ptr = (fsl_osal_ptr)((fsl_osal_u32)buf + PRE_SIZE + size1);
		fsl_osal_memset(ptr, MAGICNUMBER, AFT_SIZE);
		buf = (fsl_osal_ptr)((fsl_osal_u32)buf + PRE_SIZE);
#endif

		bt->size = size;
		bt->age = tm->age;
		bt->mem = buf;
		bt->line = line;
		bt->next = NULL;

		fsl_osal_memcpy(bt->desstring, desc, STR_LEN);
		bt->desstring[STR_LEN-1] = '\0';
		//printf("age: %d, in %s:%d allocate %p, size %d.\n",bt->age, desc, bt->line, (fsl_osal_s32)buf, size);

		if (tm->tail)
		{
			(tm->tail)->next = bt;
			tm->tail = bt;
		}
		else
		{
			tm->head = tm->tail = bt;
		}
	}
	else
	{
		if (buf)
		{
			fsl_osal_dealloc(buf);
			buf = NULL;
		}
		else
		{
			printf("%s: FATAL ERROR - Can not allocate %ld bytes\n", tm->shortname, size);
		}
		printf("FATAL ERROR: Can not allocate memory for memmanager!!\n");
	}

	return buf;
}