// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2021 StarFive Technology Co., Ltd. */ #include #include #include #include #include "SF_OMX_Core.h" static int gInitialized = 0; OMX_TICKS gInitTimeStamp = 0; int gDebugLevel = SF_LOG_ERR; extern SF_OMX_COMPONENT sf_dec_decoder_h265; extern SF_OMX_COMPONENT sf_dec_decoder_h264; static SF_OMX_COMPONENT *sf_omx_component_list[] = { &sf_dec_decoder_h265, &sf_dec_decoder_h264, NULL, }; #define SF_OMX_COMPONENT_NUM (sizeof(sf_omx_component_list) / sizeof(SF_OMX_COMPONENT *)) int GetNumberOfComponent() { return sizeof(sf_omx_component_list) / sizeof(SF_OMX_COMPONENT *); } OMX_ERRORTYPE SF_OMX_ComponentLoad(SF_OMX_COMPONENT *sf_component) { OMX_ERRORTYPE ret = OMX_ErrorNone; FunctionIn(); sf_component->SF_OMX_ComponentConstructor(sf_component); FunctionOut(); return ret; } OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void) { OMX_ERRORTYPE ret = OMX_ErrorNone; char *debugLevel = NULL; FunctionIn(); if (gInitialized == 0) { gInitialized = 1; } debugLevel = getenv("OMX_DEBUG"); if (debugLevel != NULL) { gDebugLevel = atoi(debugLevel); } FunctionOut(); return ret; } OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void) { OMX_ERRORTYPE ret = OMX_ErrorNone; FunctionIn(); FunctionOut(); return ret; } OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum( OMX_OUT OMX_STRING cComponentName, OMX_IN OMX_U32 nNameLength, OMX_IN OMX_U32 nIndex) { OMX_ERRORTYPE ret = OMX_ErrorNone; FunctionIn(); if (nIndex >= SF_OMX_COMPONENT_NUM) { ret = OMX_ErrorNoMore; goto EXIT; } snprintf(cComponentName, nNameLength, "%s", sf_omx_component_list[nIndex]->componentName); EXIT: FunctionOut(); return ret; } OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle( OMX_OUT OMX_HANDLETYPE *pHandle, OMX_IN OMX_STRING cComponentName, OMX_IN OMX_PTR pAppData, OMX_IN OMX_CALLBACKTYPE *pCallBacks) { OMX_ERRORTYPE ret = OMX_ErrorNone; unsigned int i = 0; SF_OMX_COMPONENT *pSf_omx_component = NULL; FunctionIn(); if (gInitialized != 1) { ret = OMX_ErrorNotReady; goto EXIT; } if ((pHandle == NULL) || (cComponentName == NULL)) { ret = OMX_ErrorBadParameter; goto EXIT; } for (i = 0; i < SF_OMX_COMPONENT_NUM; i++) { pSf_omx_component = sf_omx_component_list[i]; if (pSf_omx_component == NULL) { ret = OMX_ErrorBadParameter; goto EXIT; } if (strcmp(cComponentName, pSf_omx_component->componentName) == 0) { ret = pSf_omx_component->SF_OMX_ComponentConstructor(pSf_omx_component); if (ret != OMX_ErrorNone) { goto EXIT; } *pHandle = pSf_omx_component->pOMXComponent; pSf_omx_component->callbacks = pCallBacks; pSf_omx_component->pAppData = pAppData; break; } } EXIT: FunctionOut(); return ret; } OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComponent) { OMX_ERRORTYPE ret = OMX_ErrorNone; OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; SF_OMX_COMPONENT *pSfOMXComponent = (SF_OMX_COMPONENT *)pOMXComponent->pComponentPrivate; FunctionIn(); ret = pSfOMXComponent->SF_OMX_ComponentClear(pSfOMXComponent); FunctionOut(); return ret; } OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel( OMX_IN OMX_HANDLETYPE hOutput, OMX_IN OMX_U32 nPortOutput, OMX_IN OMX_HANDLETYPE hInput, OMX_IN OMX_U32 nPortInput) { OMX_ERRORTYPE ret = OMX_ErrorNone; // OMX_COMPONENTTYPE *pOMXComponent_hOutput = (OMX_COMPONENTTYPE *)hOutput; // OMX_COMPONENTTYPE *pOMXComponent_hInput = (OMX_COMPONENTTYPE *)hInput; FunctionIn(); ret = OMX_ErrorNotImplemented; FunctionOut(); return ret; } OMX_API OMX_ERRORTYPE OMX_GetContentPipe( OMX_OUT OMX_HANDLETYPE *hPipe, OMX_IN OMX_STRING szURI) { OMX_ERRORTYPE ret = OMX_ErrorNone; FunctionIn(); FunctionOut(); return ret; } OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole( OMX_IN OMX_STRING role, OMX_INOUT OMX_U32 *pNumComps, OMX_INOUT OMX_U8 **compNames) { OMX_ERRORTYPE ret = OMX_ErrorNone; FunctionIn(); FunctionOut(); return ret; } OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent( OMX_IN OMX_STRING compName, OMX_INOUT OMX_U32 *pNumRoles, OMX_OUT OMX_U8 **roles) { OMX_ERRORTYPE ret = OMX_ErrorNone; FunctionIn(); FunctionOut(); return ret; } void sf_get_component_functions(SF_COMPONENT_FUNCTIONS *funcs, OMX_PTR *sohandle) { FunctionIn(); funcs->ComponentCreate = dlsym(sohandle, "ComponentCreate"); funcs->ComponentExecute = dlsym(sohandle, "ComponentExecute"); funcs->ComponentGetParameter = dlsym(sohandle, "ComponentGetParameter"); funcs->ComponentGetState = dlsym(sohandle, "ComponentGetState"); funcs->ComponentNotifyListeners = dlsym(sohandle, "ComponentNotifyListeners"); funcs->ComponentPortCreate = dlsym(sohandle, "ComponentPortCreate"); funcs->ComponentPortDestroy = dlsym(sohandle, "ComponentPortDestroy"); funcs->ComponentPortFlush = dlsym(sohandle, "ComponentPortFlush"); funcs->ComponentPortGetData = dlsym(sohandle, "ComponentPortGetData"); funcs->ComponentPortPeekData = dlsym(sohandle, "ComponentPortPeekData"); funcs->ComponentPortSetData = dlsym(sohandle, "ComponentPortSetData"); funcs->ComponentPortWaitReadyStatus = dlsym(sohandle, "ComponentPortWaitReadyStatus"); funcs->ComponentRelease = dlsym(sohandle, "ComponentRelease"); funcs->ComponentSetParameter = dlsym(sohandle, "ComponentSetParameter"); funcs->ComponentStop = dlsym(sohandle, "ComponentStop"); funcs->ComponentSetupTunnel = dlsym(sohandle, "ComponentSetupTunnel"); funcs->ComponentWait = dlsym(sohandle, "ComponentWait"); funcs->WaitBeforeComponentPortGetData = dlsym(sohandle, "WaitBeforeComponentPortGetData"); funcs->ComponentChangeState = dlsym(sohandle, "ComponentChangeState"); funcs->ComponentDestroy = dlsym(sohandle, "ComponentDestroy"); funcs->ComponentRegisterListener = dlsym(sohandle, "ComponentRegisterListener"); funcs->ComponentPortHasInputData = dlsym(sohandle, "ComponentPortHasInputData"); funcs->ComponentPortGetSize = dlsym(sohandle, "ComponentPortGetSize"); funcs->ComponentParamReturnTest = dlsym(sohandle, "ComponentParamReturnTest"); //Listener funcs->SetupDecListenerContext = dlsym(sohandle, "SetupDecListenerContext"); funcs->SetupEncListenerContext = dlsym(sohandle, "SetupEncListenerContext"); funcs->ClearDecListenerContext = dlsym(sohandle, "ClearDecListenerContext"); funcs->HandleDecCompleteSeqEvent = dlsym(sohandle, "HandleDecCompleteSeqEvent"); funcs->HandleDecRegisterFbEvent = dlsym(sohandle, "HandleDecRegisterFbEvent"); funcs->HandleDecGetOutputEvent = dlsym(sohandle, "HandleDecGetOutputEvent"); funcs->HandleDecCloseEvent = dlsym(sohandle, "HandleDecCloseEvent"); funcs->ClearEncListenerContext = dlsym(sohandle, "ClearEncListenerContext"); funcs->HandleEncFullEvent = dlsym(sohandle, "HandleEncFullEvent"); funcs->HandleEncGetOutputEvent = dlsym(sohandle, "HandleEncGetOutputEvent"); funcs->HandleEncCompleteSeqEvent = dlsym(sohandle, "HandleEncCompleteSeqEvent"); funcs->HandleEncGetEncCloseEvent = dlsym(sohandle, "HandleEncGetEncCloseEvent"); funcs->EncoderListener = dlsym(sohandle, "EncoderListener"); funcs->DecoderListener = dlsym(sohandle, "DecoderListener"); // Helper funcs->SetDefaultEncTestConfig = dlsym(sohandle, "SetDefaultEncTestConfig"); funcs->SetDefaultDecTestConfig = dlsym(sohandle, "SetDefaultDecTestConfig"); funcs->LoadFirmware = dlsym(sohandle, "LoadFirmware"); funcs->SetupEncoderOpenParam = dlsym(sohandle, "SetupEncoderOpenParam"); funcs->SetUpDecoderOpenParam = dlsym(sohandle, "SetUpDecoderOpenParam"); // VPU funcs->VPU_GetProductId = dlsym(sohandle, "VPU_GetProductId"); funcs->Queue_Enqueue = dlsym(sohandle, "Queue_Enqueue"); funcs->Queue_Get_Cnt = dlsym(sohandle, "Queue_Get_Cnt"); // VPU Log funcs->InitLog = dlsym(sohandle, "InitLog"); funcs->DeInitLog = dlsym(sohandle, "DeInitLog"); funcs->SetMaxLogLevel = dlsym(sohandle, "SetMaxLogLevel"); funcs->GetMaxLogLevel = dlsym(sohandle, "GetMaxLogLevel"); FunctionOut(); } SF_OMX_COMPONENT *GetSFOMXComponrntByComponent(Component *pComponent) { SF_OMX_COMPONENT *pSFOMXComponent = NULL; int size = GetNumberOfComponent(); FunctionIn(); for (int i = 0; i < size; i++) { pSFOMXComponent = sf_omx_component_list[i]; if (pSFOMXComponent == NULL) { goto EXIT; } if (pSFOMXComponent->hSFComponentExecoder == pComponent || pSFOMXComponent->hSFComponentFeeder == pComponent || pSFOMXComponent->hSFComponentRender == pComponent) { break; } } EXIT: FunctionOut(); return pSFOMXComponent; } OMX_ERRORTYPE ClearOMXBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_BUFFERHEADERTYPE *pBuffer) { OMX_U32 i = 0; for (i = 0; i < sizeof(pSfOMXComponent->pBufferArray) / sizeof(pSfOMXComponent->pBufferArray[0]); i++) { if (pSfOMXComponent->pBufferArray[i] == pBuffer) { pSfOMXComponent->pBufferArray[i] = NULL; return OMX_ErrorNone; } } if (i == sizeof(pSfOMXComponent->pBufferArray) / sizeof(pSfOMXComponent->pBufferArray[0])) { LOG(SF_LOG_ERR, "Could Not found omx buffer!\r\n"); } return OMX_ErrorBadParameter; } OMX_U32 GetOMXBufferCount(SF_OMX_COMPONENT *pSfOMXComponent) { OMX_U32 i = 0; OMX_U32 count = 0; for (i = 0; i < sizeof(pSfOMXComponent->pBufferArray) / sizeof(pSfOMXComponent->pBufferArray[0]); i++) { if (pSfOMXComponent->pBufferArray[i] != NULL) { count++; } } return count; } OMX_ERRORTYPE StoreOMXBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_BUFFERHEADERTYPE *pBuffer) { OMX_U32 i = 0; for (i = 0; i < sizeof(pSfOMXComponent->pBufferArray) / sizeof(pSfOMXComponent->pBufferArray[0]); i++) { if (pSfOMXComponent->pBufferArray[i] == NULL) { pSfOMXComponent->pBufferArray[i] = pBuffer; return OMX_ErrorNone; } } if (i == sizeof(pSfOMXComponent->pBufferArray)) { LOG(SF_LOG_ERR, "Buffer arrary full!\r\n"); } return OMX_ErrorInsufficientResources; } OMX_BUFFERHEADERTYPE *GetOMXBufferByAddr(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U8 *pAddr) { OMX_U32 i = 0; OMX_BUFFERHEADERTYPE *pOMXBuffer; for (i = 0; i < sizeof(pSfOMXComponent->pBufferArray) / sizeof(pSfOMXComponent->pBufferArray[0]); i++) { pOMXBuffer = pSfOMXComponent->pBufferArray[i]; if (pOMXBuffer->pBuffer == pAddr) { return pOMXBuffer; } } if (i == sizeof(pSfOMXComponent->pBufferArray)) { LOG(SF_LOG_ERR, "could not find buffer!\r\n"); } return NULL; } void SF_LogMsg(int level, const char *function, int line, const char *format, ...) { char *prefix = ""; va_list ptr; struct timeval tv; if (level > gDebugLevel) { return; } switch (level) { case SF_LOG_ERR: prefix = "[ERROR]"; break; case SF_LOG_WARN: prefix = "[WARN ]"; break; case SF_LOG_PERF: prefix = "[PERF ]"; break; case SF_LOG_INFO: prefix = "[INFO ]"; break; case SF_LOG_DEBUG: prefix = "[DEBUG]"; break; default: break; } gettimeofday(&tv, NULL); printf("[%06d:%06d]%10s%32s%10d\t", tv.tv_sec, tv.tv_usec, prefix, function, line); va_start(ptr, format); vprintf(format, ptr); va_end(ptr); }