/**=========================================================================**/ OMX_ERRORTYPE OMX_BASE_CB_ReturnDataNotify(OMX_HANDLETYPE hComponent, OMX_S32 nPortIndex, OMX_BUFFERHEADERTYPE* pBuffer) { OMX_COMPONENTTYPE* pComp ; OMX_BASE_PRIVATETYPE* pBaseComPvt; OMX_BASE_INTERNALTYPE* pBaseComInt; OMX_BASE_PORTTYPE *pPort; OMX_ERRORTYPE tError = OMX_ErrorNone; OMX_BASE_Entering(); OMX_BASE_REQUIRE((hComponent != NULL) && (pBuffer != NULL), OMX_ErrorBadParameter); pComp = (OMX_COMPONENTTYPE *)hComponent; pBaseComPvt = (OMX_BASE_PRIVATETYPE *)pComp->pComponentPrivate; pBaseComInt = (OMX_BASE_INTERNALTYPE*)pBaseComPvt->hOMXBaseInt; pPort = pBaseComInt->ports[nPortIndex]; TIMM_OSAL_MutexObtain(pBaseComPvt->pMutex, TIMM_OSAL_SUSPEND); /* If port is Not-Tunneled, return buffers back to the IL Client by calling * FillBufferDone/EmptyBufferDone depending on the directin of port */ if (!PORT_IS_TUNNEL(pPort)){ TIMM_OSAL_MutexRelease(pBaseComPvt->pMutex); if(pPort->tPortDefParams.eDir == OMX_DirInput) pBaseComInt->tCbInfo.EmptyBufferDone(hComponent, pComp->pApplicationPrivate, pBuffer); else if(pPort->tPortDefParams.eDir == OMX_DirOutput) pBaseComInt->tCbInfo.FillBufferDone(hComponent, pComp->pApplicationPrivate, pBuffer); TIMM_OSAL_MutexObtain(pBaseComPvt->pMutex, TIMM_OSAL_SUSPEND); } /* If port is tunneled,OpenMax components directly pass data buffers among * themselves without returning them to the IL Client, thus it calls * FillThisBuffer/EmptyThisBuffer on to the corresponding tunneled port */ else if (PORT_IS_TUNNEL(pPort) && !PORT_IS_BUFFER_SUPPLIER(pPort)) { TIMM_OSAL_MutexRelease(pBaseComPvt->pMutex); if (pPort->tPortDefParams.eDir == OMX_DirInput) { pBuffer->nOutputPortIndex = pPort->unTunnelPort; pBuffer->nInputPortIndex = pPort->tPortDefParams.nPortIndex; tError = ((OMX_COMPONENTTYPE*)(pPort->hTunnelComp))->FillThisBuffer( pPort->hTunnelComp, pBuffer); } else { pBuffer->nInputPortIndex = pPort->unTunnelPort; pBuffer->nOutputPortIndex = pPort->tPortDefParams.nPortIndex; tError = ((OMX_COMPONENTTYPE*)(pPort->hTunnelComp))->EmptyThisBuffer( pPort->hTunnelComp, pBuffer); } TIMM_OSAL_MutexObtain(pBaseComPvt->pMutex, TIMM_OSAL_SUSPEND); } /* Incase the port is Tunneled and buffer supplier, it calls FTB/ETB on the tunneled port , * but if the tunneled comp is not in executing state which results in * incorrect state operation then the buffer need to be returned to pipe which * will be processed once after the tunneled comp goes to exeucting state */ else if(PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(pPort) && (pPort->bIsPortflushed==OMX_FALSE)) { TIMM_OSAL_MutexRelease(pBaseComPvt->pMutex); if(pPort->tPortDefParams.eDir == OMX_DirInput) { pBuffer->nOutputPortIndex = pPort->unTunnelPort; pBuffer->nInputPortIndex = pPort->tPortDefParams.nPortIndex; tError = ((OMX_COMPONENTTYPE*)(pPort->hTunnelComp))->FillThisBuffer( pPort->hTunnelComp, pBuffer); if(tError != OMX_ErrorNone) TIMM_OSAL_WriteToPipe((pPort->dataPipe), &pBuffer, sizeof(pBuffer), TIMM_OSAL_SUSPEND); } else { pBuffer->nInputPortIndex = pPort->unTunnelPort; pBuffer->nOutputPortIndex = pPort->tPortDefParams.nPortIndex; tError = ((OMX_COMPONENTTYPE*)(pPort->hTunnelComp))->EmptyThisBuffer( pPort->hTunnelComp, pBuffer); if(tError != OMX_ErrorNone) TIMM_OSAL_WriteToPipe((pPort->dataPipe), &pBuffer, sizeof(pBuffer), TIMM_OSAL_SUSPEND); } TIMM_OSAL_MutexObtain(pBaseComPvt->pMutex, TIMM_OSAL_SUSPEND); } TIMM_OSAL_MutexRelease(pBaseComPvt->pMutex); EXIT: OMX_BASE_Exiting(tError); return tError; }
/** @brief the entry point for sending buffers to the alsa sink port * * This function can be called by the EmptyThisBuffer or FillThisBuffer. It depends on * the nature of the port, that can be an input or output port. */ OMX_ERRORTYPE omx_alsasink_component_port_SendBufferFunction(omx_base_PortType *openmaxStandPort, OMX_BUFFERHEADERTYPE* pBuffer) { OMX_ERRORTYPE err; OMX_U32 portIndex; OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer; omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate; OMX_BOOL SendFrame; omx_base_clock_PortType* pClockPort; int errQue; #if NO_GST_OMX_PATCH unsigned int i; #endif portIndex = (openmaxStandPort->sPortParam.eDir == OMX_DirInput)?pBuffer->nInputPortIndex:pBuffer->nOutputPortIndex; DEBUG(DEB_LEV_FUNCTION_NAME, "In %s portIndex %lu\n", __func__, portIndex); if (portIndex != openmaxStandPort->sPortParam.nPortIndex) { DEBUG(DEB_LEV_ERR, "In %s: wrong port for this operation portIndex=%d port->portIndex=%d\n", __func__, (int)portIndex, (int)openmaxStandPort->sPortParam.nPortIndex); return OMX_ErrorBadPortIndex; } if(omx_base_component_Private->state == OMX_StateInvalid) { DEBUG(DEB_LEV_ERR, "In %s: we are in OMX_StateInvalid\n", __func__); return OMX_ErrorInvalidState; } if(omx_base_component_Private->state != OMX_StateExecuting && omx_base_component_Private->state != OMX_StatePause && omx_base_component_Private->state != OMX_StateIdle) { DEBUG(DEB_LEV_ERR, "In %s: we are not in executing/paused/idle state, but in %d\n", __func__, omx_base_component_Private->state); return OMX_ErrorIncorrectStateOperation; } if (!PORT_IS_ENABLED(openmaxStandPort) || (PORT_IS_BEING_DISABLED(openmaxStandPort) && !PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) || (omx_base_component_Private->transientState == OMX_TransStateExecutingToIdle && (PORT_IS_TUNNELED(openmaxStandPort) && !PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)))) { DEBUG(DEB_LEV_ERR, "In %s: Port %d is disabled comp = %s \n", __func__, (int)portIndex,omx_base_component_Private->name); return OMX_ErrorIncorrectStateOperation; } /* Temporarily disable this check for gst-openmax */ #if NO_GST_OMX_PATCH { OMX_BOOL foundBuffer = OMX_FALSE; if(pBuffer!=NULL && pBuffer->pBuffer!=NULL) { for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){ if (pBuffer->pBuffer == openmaxStandPort->pInternalBufferStorage[i]->pBuffer) { foundBuffer = OMX_TRUE; break; } } } if (!foundBuffer) { return OMX_ErrorBadParameter; } } #endif if ((err = checkHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE))) != OMX_ErrorNone) { DEBUG(DEB_LEV_ERR, "In %s: received wrong buffer header on input port\n", __func__); return err; } pClockPort = (omx_base_clock_PortType*)omx_base_component_Private->ports[OMX_BASE_SINK_CLOCKPORT_INDEX]; if(PORT_IS_TUNNELED(pClockPort) && !PORT_IS_BEING_FLUSHED(openmaxStandPort) && (omx_base_component_Private->transientState != OMX_TransStateExecutingToIdle) && ((pBuffer->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)){ SendFrame = omx_alsasink_component_ClockPortHandleFunction((omx_alsasink_component_PrivateType*)omx_base_component_Private, pBuffer); /* drop the frame */ if(!SendFrame) pBuffer->nFilledLen=0; } /* And notify the buffer management thread we have a fresh new buffer to manage */ if(!PORT_IS_BEING_FLUSHED(openmaxStandPort) && !(PORT_IS_BEING_DISABLED(openmaxStandPort) && PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort))){ errQue = queue(openmaxStandPort->pBufferQueue, pBuffer); if (errQue) { /* /TODO the queue is full. This can be handled in a fine way with * some retrials, or other checking. For the moment this is a critical error * and simply causes the failure of this call */ return OMX_ErrorInsufficientResources; } tsem_up(openmaxStandPort->pBufferSem); DEBUG(DEB_LEV_PARAMS, "In %s Signalling bMgmtSem Port Index=%d\n",__func__, (int)portIndex); tsem_up(omx_base_component_Private->bMgmtSem); }else if(PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)){ DEBUG(DEB_LEV_FULL_SEQ, "In %s: Comp %s received io:%d buffer\n", __func__,omx_base_component_Private->name,(int)openmaxStandPort->sPortParam.nPortIndex); errQue = queue(openmaxStandPort->pBufferQueue, pBuffer); if (errQue) { /* /TODO the queue is full. This can be handled in a fine way with * some retrials, or other checking. For the moment this is a critical error * and simply causes the failure of this call */ return OMX_ErrorInsufficientResources; } tsem_up(openmaxStandPort->pBufferSem); } else { // If port being flushed and not tunneled then return error DEBUG(DEB_LEV_FULL_SEQ, "In %s \n", __func__); return OMX_ErrorIncorrectStateOperation; } return OMX_ErrorNone; }
/** @brief Releases buffers under processing. * This function must be implemented in the derived classes, for the * specific processing */ OMX_ERRORTYPE clocksrc_port_FlushProcessingBuffers(omx_base_PortType *openmaxStandPort) { omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private; OMX_BUFFERHEADERTYPE* pBuffer; int errQue; DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__); omx_clocksrc_component_Private = (omx_clocksrc_component_PrivateType*)openmaxStandPort->standCompContainer->pComponentPrivate; pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex); openmaxStandPort->bIsPortFlushed=OMX_TRUE; /*Signal the buffer management thread of port flush,if it is waiting for buffers*/ if(omx_clocksrc_component_Private->bMgmtSem->semval==0) { tsem_up(omx_clocksrc_component_Private->bMgmtSem); } tsem_up(omx_clocksrc_component_Private->clockEventSem); tsem_up(omx_clocksrc_component_Private->clockEventCompleteSem); if(omx_clocksrc_component_Private->state==OMX_StatePause ) { /*Waiting at paused state*/ tsem_signal(omx_clocksrc_component_Private->bStateSem); } DEBUG(DEB_LEV_FULL_SEQ, "In %s waiting for flush all condition port index =%d\n", __func__,(int)openmaxStandPort->sPortParam.nPortIndex); /* Wait until flush is completed */ pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex); tsem_down(omx_clocksrc_component_Private->flush_all_condition); tsem_reset(omx_clocksrc_component_Private->bMgmtSem); tsem_reset(omx_clocksrc_component_Private->clockEventSem); /* Flush all the buffers not under processing */ while (openmaxStandPort->pBufferSem->semval > 0) { DEBUG(DEB_LEV_FULL_SEQ, "In %s TFlag=%x Flusing Port=%d,Semval=%d Qelem=%d\n", __func__,(int)openmaxStandPort->nTunnelFlags,(int)openmaxStandPort->sPortParam.nPortIndex, (int)openmaxStandPort->pBufferSem->semval,(int)openmaxStandPort->pBufferQueue->nelem); tsem_down(openmaxStandPort->pBufferSem); pBuffer = dequeue(openmaxStandPort->pBufferQueue); if (PORT_IS_TUNNELED(openmaxStandPort) && !PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)) { DEBUG(DEB_LEV_FULL_SEQ, "In %s: Comp %s is returning io:%d buffer\n", __func__,omx_clocksrc_component_Private->name,(int)openmaxStandPort->sPortParam.nPortIndex); if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) { ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->FillThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer); } else { ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->EmptyThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer); } } else if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) { errQue = queue(openmaxStandPort->pBufferQueue,pBuffer); if (errQue) { /* /TODO the queue is full. This can be handled in a fine way with * some retrials, or other checking. For the moment this is a critical error * and simply causes the failure of this call */ return OMX_ErrorInsufficientResources; } } else { (*(openmaxStandPort->BufferProcessedCallback))( openmaxStandPort->standCompContainer, omx_clocksrc_component_Private->callbackData, pBuffer); } } /*Port is tunneled and supplier and didn't received all it's buffer then wait for the buffers*/ if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) { while(openmaxStandPort->pBufferQueue->nelem!= openmaxStandPort->nNumAssignedBuffers){ tsem_down(openmaxStandPort->pBufferSem); DEBUG(DEB_LEV_PARAMS, "In %s Got a buffer qelem=%d\n",__func__,openmaxStandPort->pBufferQueue->nelem); } tsem_reset(openmaxStandPort->pBufferSem); } pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex); openmaxStandPort->bIsPortFlushed=OMX_FALSE; pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex); tsem_up(omx_clocksrc_component_Private->flush_condition); DEBUG(DEB_LEV_FULL_SEQ, "Out %s Port Index=%d bIsPortFlushed=%d Component %s\n", __func__, (int)openmaxStandPort->sPortParam.nPortIndex,(int)openmaxStandPort->bIsPortFlushed,omx_clocksrc_component_Private->name); DEBUG(DEB_LEV_PARAMS, "In %s TFlag=%x Qelem=%d BSem=%d bMgmtsem=%d component=%s\n", __func__, (int)openmaxStandPort->nTunnelFlags, (int)openmaxStandPort->pBufferQueue->nelem, (int)openmaxStandPort->pBufferSem->semval, (int)omx_clocksrc_component_Private->bMgmtSem->semval, omx_clocksrc_component_Private->name); DEBUG(DEB_LEV_FUNCTION_NAME, "Out %s Port Index=%d\n", __func__,(int)openmaxStandPort->sPortParam.nPortIndex); return OMX_ErrorNone; }
OMX_ERRORTYPE videosrc_port_AllocateTunnelBuffer(omx_base_PortType *openmaxStandPort,OMX_IN OMX_U32 nPortIndex,OMX_IN OMX_U32 nSizeBytes) { int i; OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer; omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate; omx_videosrc_component_PrivateType* omx_videosrc_component_Private = (omx_videosrc_component_PrivateType*)omx_base_component_Private; OMX_U8* pBuffer=NULL; OMX_ERRORTYPE eError=OMX_ErrorNone; OMX_U32 numRetry=0; DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__); if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) { DEBUG(DEB_LEV_ERR, "In %s: Bad Port Index\n", __func__); return OMX_ErrorBadPortIndex; } if (! PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) { DEBUG(DEB_LEV_ERR, "In %s: Port is not tunneled Flag=%x\n", __func__, (int)openmaxStandPort->nTunnelFlags); return OMX_ErrorBadPortIndex; } if (omx_base_component_Private->transientState != OMX_TransStateLoadedToIdle) { if (!openmaxStandPort->bIsTransientToEnabled) { DEBUG(DEB_LEV_ERR, "In %s: The port is not allowed to receive buffers\n", __func__); return OMX_ErrorIncorrectStateTransition; } } for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){ if (openmaxStandPort->bBufferStateAllocated[i] == BUFFER_FREE) { /* Map the buffer with the device's memory area*/ if(i > n_buffers) { DEBUG(DEB_LEV_ERR, "In %s returning error i=%d, nframe=%d\n", __func__,i,n_buffers); return OMX_ErrorInsufficientResources; } omx_videosrc_component_Private->bOutBufferMemoryMapped = OMX_TRUE; pBuffer = omx_videosrc_component_Private->buffers[i].start; /*Retry more than once, if the tunneled component is not in Loaded->Idle State*/ while(numRetry <TUNNEL_USE_BUFFER_RETRY) { eError=OMX_UseBuffer(openmaxStandPort->hTunneledComponent,&openmaxStandPort->pInternalBufferStorage[i], openmaxStandPort->nTunneledPort,NULL,nSizeBytes,pBuffer); if(eError!=OMX_ErrorNone) { DEBUG(DEB_LEV_FULL_SEQ,"Tunneled Component Couldn't Use buffer %i From Comp=%s Retry=%d\n", i,omx_base_component_Private->name,(int)numRetry); if((eError == OMX_ErrorIncorrectStateTransition) && numRetry<TUNNEL_USE_BUFFER_RETRY) { DEBUG(DEB_LEV_FULL_SEQ,"Waiting for next try %i \n",(int)numRetry); usleep(TUNNEL_USE_BUFFER_RETRY_USLEEP_TIME); numRetry++; continue; } return eError; } else { break; } } openmaxStandPort->bBufferStateAllocated[i] = BUFFER_ALLOCATED; openmaxStandPort->nNumAssignedBuffers++; DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers); if (openmaxStandPort->sPortParam.nBufferCountActual == openmaxStandPort->nNumAssignedBuffers) { openmaxStandPort->sPortParam.bPopulated = OMX_TRUE; openmaxStandPort->bIsFullOfBuffers = OMX_TRUE; DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s nPortIndex=%d\n",__func__, (int)nPortIndex); } queue(openmaxStandPort->pBufferQueue, openmaxStandPort->pInternalBufferStorage[i]); } } DEBUG(DEB_LEV_FUNCTION_NAME, "In %s Allocated all buffers\n",__func__); return OMX_ErrorNone; }
OMX_ERRORTYPE videosrc_port_FreeTunnelBuffer(omx_base_PortType *openmaxStandPort,OMX_U32 nPortIndex) { int i; OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer; omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate; omx_videosrc_component_PrivateType* omx_videosrc_component_Private = (omx_videosrc_component_PrivateType*)omx_base_component_Private; OMX_ERRORTYPE eError=OMX_ErrorNone; OMX_U32 numRetry=0; DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__); if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) { DEBUG(DEB_LEV_ERR, "In %s: Bad Port Index\n", __func__); return OMX_ErrorBadPortIndex; } if (! PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) { DEBUG(DEB_LEV_ERR, "In %s: Port is not tunneled\n", __func__); return OMX_ErrorBadPortIndex; } if (omx_base_component_Private->transientState != OMX_TransStateIdleToLoaded) { if (!openmaxStandPort->bIsTransientToDisabled) { DEBUG(DEB_LEV_FULL_SEQ, "In %s: The port is not allowed to free the buffers\n", __func__); (*(omx_base_component_Private->callbacks->EventHandler)) (omxComponent, omx_base_component_Private->callbackData, OMX_EventError, /* The command was completed */ OMX_ErrorPortUnpopulated, /* The commands was a OMX_CommandStateSet */ nPortIndex, /* The state has been changed in message->messageParam2 */ NULL); } } for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){ if (openmaxStandPort->bBufferStateAllocated[i] & (BUFFER_ASSIGNED | BUFFER_ALLOCATED)) { openmaxStandPort->bIsFullOfBuffers = OMX_FALSE; if (openmaxStandPort->bBufferStateAllocated[i] & BUFFER_ALLOCATED) { openmaxStandPort->pInternalBufferStorage[i]->pBuffer = NULL; omx_videosrc_component_Private->bOutBufferMemoryMapped = OMX_FALSE; } /*Retry more than once, if the tunneled component is not in Idle->Loaded State*/ while(numRetry <TUNNEL_USE_BUFFER_RETRY) { eError=OMX_FreeBuffer(openmaxStandPort->hTunneledComponent,openmaxStandPort->nTunneledPort,openmaxStandPort->pInternalBufferStorage[i]); if(eError!=OMX_ErrorNone) { DEBUG(DEB_LEV_ERR,"Tunneled Component Couldn't free buffer %i \n",i); if((eError == OMX_ErrorIncorrectStateTransition) && numRetry<TUNNEL_USE_BUFFER_RETRY) { DEBUG(DEB_LEV_ERR,"Waiting for next try %i \n",(int)numRetry); usleep(TUNNEL_USE_BUFFER_RETRY_USLEEP_TIME); numRetry++; continue; } return eError; } else { break; } } openmaxStandPort->bBufferStateAllocated[i] = BUFFER_FREE; openmaxStandPort->nNumAssignedBuffers--; DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers); if (openmaxStandPort->nNumAssignedBuffers == 0) { openmaxStandPort->sPortParam.bPopulated = OMX_FALSE; openmaxStandPort->bIsEmptyOfBuffers = OMX_TRUE; //tsem_up(openmaxStandPort->pAllocSem); } } } DEBUG(DEB_LEV_FUNCTION_NAME, "In %s Qelem=%d BSem=%d\n", __func__,openmaxStandPort->pBufferQueue->nelem,openmaxStandPort->pBufferSem->semval); return OMX_ErrorNone; }
OMX_ERRORTYPE videosrc_port_AllocateBuffer( omx_base_PortType *openmaxStandPort, OMX_BUFFERHEADERTYPE** pBuffer, OMX_U32 nPortIndex, OMX_PTR pAppPrivate, OMX_U32 nSizeBytes) { int i; OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer; omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate; omx_videosrc_component_PrivateType* omx_videosrc_component_Private = (omx_videosrc_component_PrivateType*)omx_base_component_Private; DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__); if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) { return OMX_ErrorBadPortIndex; } if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) { return OMX_ErrorBadPortIndex; } if (omx_base_component_Private->transientState != OMX_TransStateLoadedToIdle) { if (!openmaxStandPort->bIsTransientToEnabled) { DEBUG(DEB_LEV_ERR, "In %s: The port is not allowed to receive buffers\n", __func__); return OMX_ErrorIncorrectStateTransition; } } if(nSizeBytes < openmaxStandPort->sPortParam.nBufferSize) { DEBUG(DEB_LEV_ERR, "In %s: Requested Buffer Size %lu is less than Minimum Buffer Size %lu\n", __func__, nSizeBytes, openmaxStandPort->sPortParam.nBufferSize); return OMX_ErrorIncorrectStateTransition; } for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){ if (openmaxStandPort->bBufferStateAllocated[i] == BUFFER_FREE) { openmaxStandPort->pInternalBufferStorage[i] = calloc(1,sizeof(OMX_BUFFERHEADERTYPE)); if (!openmaxStandPort->pInternalBufferStorage[i]) { return OMX_ErrorInsufficientResources; } setHeader(openmaxStandPort->pInternalBufferStorage[i], sizeof(OMX_BUFFERHEADERTYPE)); /* Map the buffer with the device's memory area*/ if(i > n_buffers) { DEBUG(DEB_LEV_ERR, "In %s returning error i=%d, nframe=%d\n", __func__,i,n_buffers); return OMX_ErrorInsufficientResources; } omx_videosrc_component_Private->bOutBufferMemoryMapped = OMX_TRUE; openmaxStandPort->pInternalBufferStorage[i]->pBuffer = omx_videosrc_component_Private->buffers[i].start; openmaxStandPort->pInternalBufferStorage[i]->nAllocLen = (int)nSizeBytes; openmaxStandPort->pInternalBufferStorage[i]->pPlatformPrivate = openmaxStandPort; openmaxStandPort->pInternalBufferStorage[i]->pAppPrivate = pAppPrivate; *pBuffer = openmaxStandPort->pInternalBufferStorage[i]; openmaxStandPort->bBufferStateAllocated[i] = BUFFER_ALLOCATED; openmaxStandPort->bBufferStateAllocated[i] |= HEADER_ALLOCATED; if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) { openmaxStandPort->pInternalBufferStorage[i]->nInputPortIndex = openmaxStandPort->sPortParam.nPortIndex; } else { openmaxStandPort->pInternalBufferStorage[i]->nOutputPortIndex = openmaxStandPort->sPortParam.nPortIndex; } openmaxStandPort->nNumAssignedBuffers++; DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers); if (openmaxStandPort->sPortParam.nBufferCountActual == openmaxStandPort->nNumAssignedBuffers) { openmaxStandPort->sPortParam.bPopulated = OMX_TRUE; openmaxStandPort->bIsFullOfBuffers = OMX_TRUE; DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s nPortIndex=%d\n",__func__,(int)nPortIndex); tsem_up(openmaxStandPort->pAllocSem); } return OMX_ErrorNone; } } DEBUG(DEB_LEV_ERR, "In %s Error: no available buffers\n",__func__); return OMX_ErrorInsufficientResources; }
OMX_ERRORTYPE videosrc_port_FreeBuffer( omx_base_PortType *openmaxStandPort, OMX_U32 nPortIndex, OMX_BUFFERHEADERTYPE* pBuffer) { int i; OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer; omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate; omx_videosrc_component_PrivateType* omx_videosrc_component_Private = (omx_videosrc_component_PrivateType*)omx_base_component_Private; DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__); if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) { return OMX_ErrorBadPortIndex; } if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) { return OMX_ErrorBadPortIndex; } if (omx_base_component_Private->transientState != OMX_TransStateIdleToLoaded) { if (!openmaxStandPort->bIsTransientToDisabled) { DEBUG(DEB_LEV_FULL_SEQ, "In %s: The port is not allowed to free the buffers\n", __func__); (*(omx_base_component_Private->callbacks->EventHandler)) (omxComponent, omx_base_component_Private->callbackData, OMX_EventError, /* The command was completed */ OMX_ErrorPortUnpopulated, /* The commands was a OMX_CommandStateSet */ nPortIndex, /* The state has been changed in message->messageParam2 */ NULL); } } for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){ if (openmaxStandPort->bBufferStateAllocated[i] & (BUFFER_ASSIGNED | BUFFER_ALLOCATED)) { openmaxStandPort->bIsFullOfBuffers = OMX_FALSE; if (openmaxStandPort->bBufferStateAllocated[i] & BUFFER_ALLOCATED) { if(openmaxStandPort->pInternalBufferStorage[i]->pBuffer){ DEBUG(DEB_LEV_PARAMS, "In %s freeing %i pBuffer=%x\n",__func__, (int)i, (int)openmaxStandPort->pInternalBufferStorage[i]->pBuffer); openmaxStandPort->pInternalBufferStorage[i]->pBuffer=NULL; omx_videosrc_component_Private->bOutBufferMemoryMapped = OMX_FALSE; } } else if (openmaxStandPort->bBufferStateAllocated[i] & BUFFER_ASSIGNED) { free(pBuffer); pBuffer=NULL; } if(openmaxStandPort->bBufferStateAllocated[i] & HEADER_ALLOCATED) { free(openmaxStandPort->pInternalBufferStorage[i]); openmaxStandPort->pInternalBufferStorage[i]=NULL; } openmaxStandPort->bBufferStateAllocated[i] = BUFFER_FREE; openmaxStandPort->nNumAssignedBuffers--; DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers); if (openmaxStandPort->nNumAssignedBuffers == 0) { openmaxStandPort->sPortParam.bPopulated = OMX_FALSE; openmaxStandPort->bIsEmptyOfBuffers = OMX_TRUE; tsem_up(openmaxStandPort->pAllocSem); } return OMX_ErrorNone; } } return OMX_ErrorInsufficientResources; }
/** @brief Called by the standard allocate buffer, it implements a base functionality. * * This function can be overriden if the allocation of the buffer is not a simply alloc call. * The parameters are the same as the standard function, except for the handle of the port * instead of the handler of the component * When the buffers needed by this port are all assigned or allocated, the variable * bIsFullOfBuffers becomes equal to OMX_TRUE */ OMX_ERRORTYPE camera_video_port_AllocateBuffer( omx_base_PortType *openmaxStandPort, OMX_BUFFERHEADERTYPE **pBuffer, OMX_U32 nPortIndex, OMX_PTR pAppPrivate, OMX_U32 nSizeBytes) { unsigned int i; OMX_COMPONENTTYPE *omxComponent = openmaxStandPort->standCompContainer; omx_base_component_PrivateType *omx_base_component_Private = (omx_base_component_PrivateType *)omxComponent->pComponentPrivate; omx_base_camera_video_PortType *omx_base_video_Port = (omx_base_camera_video_PortType *)openmaxStandPort; OMXDBUG(OMXDBUG_VERB, "In %s for port %p\n", __func__, openmaxStandPort); if(nPortIndex != openmaxStandPort->sPortParam.nPortIndex) { return OMX_ErrorBadPortIndex; } if(PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) { return OMX_ErrorBadPortIndex; } if(omx_base_component_Private->transientState != OMX_TransStateLoadedToIdle) { if(!openmaxStandPort->bIsTransientToEnabled) { OMXDBUG(OMXDBUG_ERR, "In %s: The port is not allowed to receive buffers\n", __func__); return OMX_ErrorIncorrectStateTransition; } } if(nSizeBytes < openmaxStandPort->sPortParam.nBufferSize) { OMXDBUG(OMXDBUG_ERR, "In %s: Requested Buffer Size %lu is less than Minimum Buffer Size %lu\n", __func__, nSizeBytes, openmaxStandPort->sPortParam.nBufferSize); return OMX_ErrorIncorrectStateTransition; } if(omx_base_video_Port->pBufferHeadAct == NULL) { omx_base_video_Port->pBufferHeadAct = calloc(openmaxStandPort->sPortParam.nBufferCountActual, sizeof(OMX_BUFFERHEADERTYPE_ACTEXT)); if(omx_base_video_Port->pBufferHeadAct == NULL) { return OMX_ErrorInsufficientResources; } } for(i = 0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++) { if(openmaxStandPort->bBufferStateAllocated[i] == BUFFER_FREE) { openmaxStandPort->pInternalBufferStorage[i] = calloc(1, sizeof(OMX_BUFFERHEADERTYPE)); if(!openmaxStandPort->pInternalBufferStorage[i]) { return OMX_ErrorInsufficientResources; } setHeader(openmaxStandPort->pInternalBufferStorage[i], sizeof(OMX_BUFFERHEADERTYPE)); /* allocate the buffer */ #if 0 openmaxStandPort->pInternalBufferStorage[i]->pBuffHead.pBuffer = calloc(1, nSizeBytes); #else { unsigned long pVirAddr = 0; openmaxStandPort->pInternalBufferStorage[i]->pBuffer = (OMX_U8 *)ext_phycalloc_mem(1, nSizeBytes, (void *)&pVirAddr); omx_base_video_Port->pBufferHeadAct[i].pConfigParam.VirAddr = (OMX_U8 *)pVirAddr; omx_base_video_Port->pBufferHeadAct[i].pConfigParam.phyAddr = openmaxStandPort->pInternalBufferStorage[i]->pBuffer; openmaxStandPort->pInternalBufferStorage[i]->pBuffer = omx_base_video_Port->pBufferHeadAct[i].pConfigParam.VirAddr; omx_base_video_Port->pBufferHeadAct[i].pConfigParam.bAllocByComp = OMX_TRUE; } #endif if(openmaxStandPort->pInternalBufferStorage[i]->pBuffer == NULL) { return OMX_ErrorInsufficientResources; } omx_base_video_Port->pBufferHeadAct[i].pBuffHead = openmaxStandPort->pInternalBufferStorage[i]; openmaxStandPort->pInternalBufferStorage[i]->nAllocLen = nSizeBytes; openmaxStandPort->pInternalBufferStorage[i]->pPlatformPrivate = openmaxStandPort; openmaxStandPort->pInternalBufferStorage[i]->pAppPrivate = pAppPrivate; *pBuffer = (OMX_BUFFERHEADERTYPE *)openmaxStandPort->pInternalBufferStorage[i]; openmaxStandPort->bBufferStateAllocated[i] = BUFFER_ALLOCATED; openmaxStandPort->bBufferStateAllocated[i] |= HEADER_ALLOCATED; if(openmaxStandPort->sPortParam.eDir == OMX_DirInput) { openmaxStandPort->pInternalBufferStorage[i]->nInputPortIndex = openmaxStandPort->sPortParam.nPortIndex; } else { openmaxStandPort->pInternalBufferStorage[i]->nOutputPortIndex = openmaxStandPort->sPortParam.nPortIndex; } openmaxStandPort->nNumAssignedBuffers++; OMXDBUG(OMXDBUG_VERB, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers); if(openmaxStandPort->sPortParam.nBufferCountActual == openmaxStandPort->nNumAssignedBuffers) { openmaxStandPort->sPortParam.bPopulated = OMX_TRUE; openmaxStandPort->bIsFullOfBuffers = OMX_TRUE; OMXDBUG(OMXDBUG_VERB, "In %s nPortIndex=%d\n", __func__, (int)nPortIndex); tsem_up(openmaxStandPort->pAllocSem); } OMXDBUG(OMXDBUG_VERB, "Out of %s for port %p\n", __func__, openmaxStandPort); return OMX_ErrorNone; } } OMXDBUG(OMXDBUG_ERR, "Out of %s for port %p. Error: no available buffers\n", __func__, openmaxStandPort); return OMX_ErrorInsufficientResources; }
/** @brief the entry point for sending buffers to the port * * This function can be called by the EmptyThisBuffer or FillThisBuffer. It depends on * the nature of the port, that can be an input or output port. */ OMX_ERRORTYPE base_clock_port_SendBufferFunction( omx_base_PortType *openmaxStandPort, OMX_BUFFERHEADERTYPE* pBuffer) { OMX_ERRORTYPE err; OMX_U32 portIndex; OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer; omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate; #if NO_GST_OMX_PATCH unsigned int i; #endif portIndex = (openmaxStandPort->sPortParam.eDir == OMX_DirInput)?pBuffer->nInputPortIndex:pBuffer->nOutputPortIndex; DEBUG(DEB_LEV_FUNCTION_NAME, "In %s portIndex %lu\n", __func__, portIndex); if (portIndex != openmaxStandPort->sPortParam.nPortIndex) { DEBUG(DEB_LEV_ERR, "In %s: wrong port for this operation portIndex=%d port->portIndex=%d\n", __func__, (int)portIndex, (int)openmaxStandPort->sPortParam.nPortIndex); return OMX_ErrorBadPortIndex; } if(omx_base_component_Private->state == OMX_StateInvalid) { DEBUG(DEB_LEV_ERR, "In %s: we are in OMX_StateInvalid\n", __func__); return OMX_ErrorInvalidState; } if(omx_base_component_Private->state != OMX_StateExecuting && omx_base_component_Private->state != OMX_StatePause && omx_base_component_Private->state != OMX_StateIdle) { DEBUG(DEB_LEV_ERR, "In %s: we are not in executing/paused/idle state, but in %d\n", __func__, omx_base_component_Private->state); return OMX_ErrorIncorrectStateOperation; } if (!PORT_IS_ENABLED(openmaxStandPort) || (PORT_IS_BEING_DISABLED(openmaxStandPort) && !PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) || (omx_base_component_Private->transientState == OMX_TransStateExecutingToIdle && (PORT_IS_TUNNELED(openmaxStandPort) && !PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)))) { DEBUG(DEB_LEV_ERR, "In %s: Port %d is disabled comp = %s \n", __func__, (int)portIndex,omx_base_component_Private->name); return OMX_ErrorIncorrectStateOperation; } /* Temporarily disable this check for gst-openmax */ #if NO_GST_OMX_PATCH { OMX_BOOL foundBuffer = OMX_FALSE; if(pBuffer!=NULL && pBuffer->pBuffer!=NULL) { for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){ if (pBuffer->pBuffer == openmaxStandPort->pInternalBufferStorage[i]->pBuffer) { foundBuffer = OMX_TRUE; break; } } } if (!foundBuffer) { return OMX_ErrorBadParameter; } } #endif if ((err = checkHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE))) != OMX_ErrorNone) { DEBUG(DEB_LEV_ERR, "In %s: received wrong buffer header on input port\n", __func__); return err; } /*If port is not tunneled then simply return the buffer except paused state*/ if (!PORT_IS_TUNNELED(openmaxStandPort) && (omx_base_component_Private->state != OMX_StatePause)) { openmaxStandPort->ReturnBufferFunction(openmaxStandPort,pBuffer); return OMX_ErrorNone; } /* And notify the buffer management thread we have a fresh new buffer to manage */ if(!PORT_IS_BEING_FLUSHED(openmaxStandPort) && !(PORT_IS_BEING_DISABLED(openmaxStandPort) && PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort))){ queue(openmaxStandPort->pBufferQueue, pBuffer); tsem_up(openmaxStandPort->pBufferSem); DEBUG(DEB_LEV_PARAMS, "In %s Signalling bMgmtSem Port Index=%d\n",__func__, (int)portIndex); tsem_up(omx_base_component_Private->bMgmtSem); }else if(PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)){ DEBUG(DEB_LEV_FULL_SEQ, "In %s: Comp %s received io:%d buffer\n", __func__,omx_base_component_Private->name,(int)openmaxStandPort->sPortParam.nPortIndex); queue(openmaxStandPort->pBufferQueue, pBuffer); tsem_up(openmaxStandPort->pBufferSem); } else { // If port being flushed and not tunneled then return error DEBUG(DEB_LEV_FULL_SEQ, "In %s \n", __func__); return OMX_ErrorIncorrectStateOperation; } return OMX_ErrorNone; }
/** @brief Called by the standard use buffer, it implements a base functionality. * * This function can be overriden if the use buffer implicate more complicated operations. * The parameters are the same as the standard function, except for the handle of the port * instead of the handler of the component. * When the buffers needed by this port are all assigned or allocated, the variable * bIsFullOfBuffers becomes equal to OMX_TRUE */ OMX_ERRORTYPE camera_video_port_UseBuffer( omx_base_PortType *openmaxStandPort, OMX_BUFFERHEADERTYPE **ppBufferHdr, OMX_U32 nPortIndex, OMX_PTR pAppPrivate, OMX_U32 nSizeBytes, OMX_U8 *pBuffer) { unsigned int i; OMX_BUFFERHEADERTYPE *returnBufferHeader; omx_base_camera_video_PortType *pBasePort = (omx_base_camera_video_PortType *)openmaxStandPort; OMX_COMPONENTTYPE *omxComponent = openmaxStandPort->standCompContainer; omx_base_component_PrivateType *omx_base_component_Private = (omx_base_component_PrivateType *)omxComponent->pComponentPrivate; omx_base_camera_video_PortType *omx_base_video_Port = (omx_base_camera_video_PortType *)openmaxStandPort; OMXDBUG(OMXDBUG_VERB, "In %s for port %p\n", __func__, openmaxStandPort); if(nPortIndex != openmaxStandPort->sPortParam.nPortIndex) { return OMX_ErrorBadPortIndex; } if(PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) { return OMX_ErrorBadPortIndex; } if(omx_base_component_Private->transientState != OMX_TransStateLoadedToIdle) { if(!openmaxStandPort->bIsTransientToEnabled) { OMXDBUG(OMXDBUG_ERR, "In %s: The port of Comp %s is not allowed to receive buffers\n", __func__, omx_base_component_Private->name); return OMX_ErrorIncorrectStateTransition; } } if(pBasePort->bStoreMediadata == OMX_FALSE && nSizeBytes < openmaxStandPort->sPortParam.nBufferSize) { OMXDBUG(OMXDBUG_ERR, "In %s: Port %d Given Buffer Size %u is less than Minimum Buffer Size %u\n", __func__, (int)nPortIndex, (int)nSizeBytes, (int)openmaxStandPort->sPortParam.nBufferSize); return OMX_ErrorIncorrectStateTransition; } if(omx_base_video_Port->pBufferHeadAct == NULL) { omx_base_video_Port->pBufferHeadAct = calloc(openmaxStandPort->sPortParam.nBufferCountActual, sizeof(OMX_BUFFERHEADERTYPE_ACTEXT)); if(omx_base_video_Port->pBufferHeadAct == NULL) { return OMX_ErrorInsufficientResources; } } for(i = 0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++) { if(openmaxStandPort->bBufferStateAllocated[i] == BUFFER_FREE) { openmaxStandPort->pInternalBufferStorage[i] = calloc(1, sizeof(OMX_BUFFERHEADERTYPE)); if(!openmaxStandPort->pInternalBufferStorage[i]) { return OMX_ErrorInsufficientResources; } openmaxStandPort->bIsEmptyOfBuffers = OMX_FALSE; setHeader(openmaxStandPort->pInternalBufferStorage[i], sizeof(OMX_BUFFERHEADERTYPE)); openmaxStandPort->pInternalBufferStorage[i]->pBuffer = pBuffer; openmaxStandPort->pInternalBufferStorage[i]->nAllocLen = nSizeBytes; openmaxStandPort->pInternalBufferStorage[i]->pPlatformPrivate = openmaxStandPort; openmaxStandPort->pInternalBufferStorage[i]->pAppPrivate = pAppPrivate; openmaxStandPort->bBufferStateAllocated[i] = BUFFER_ASSIGNED; openmaxStandPort->bBufferStateAllocated[i] |= HEADER_ALLOCATED; returnBufferHeader = calloc(1, sizeof(OMX_BUFFERHEADERTYPE)); if(!returnBufferHeader) { return OMX_ErrorInsufficientResources; } omx_base_video_Port->pBufferHeadAct[i].pBuffHead = returnBufferHeader; setHeader(returnBufferHeader, sizeof(OMX_BUFFERHEADERTYPE)); returnBufferHeader->pBuffer = pBuffer; returnBufferHeader->nAllocLen = nSizeBytes; returnBufferHeader->pPlatformPrivate = openmaxStandPort; returnBufferHeader->pAppPrivate = pAppPrivate; if(openmaxStandPort->sPortParam.eDir == OMX_DirInput) { openmaxStandPort->pInternalBufferStorage[i]->nInputPortIndex = openmaxStandPort->sPortParam.nPortIndex; returnBufferHeader->nInputPortIndex = openmaxStandPort->sPortParam.nPortIndex; } else { openmaxStandPort->pInternalBufferStorage[i]->nOutputPortIndex = openmaxStandPort->sPortParam.nPortIndex; returnBufferHeader->nOutputPortIndex = openmaxStandPort->sPortParam.nPortIndex; } *ppBufferHdr = (OMX_BUFFERHEADERTYPE *)returnBufferHeader; openmaxStandPort->nNumAssignedBuffers++; OMXDBUG(OMXDBUG_VERB, "openmaxStandPort->nNumAssignedBuffers %d,%d\n", (unsigned int)openmaxStandPort->sPortParam.nBufferCountActual, (unsigned int)openmaxStandPort->nNumAssignedBuffers); if(openmaxStandPort->sPortParam.nBufferCountActual == openmaxStandPort->nNumAssignedBuffers) { openmaxStandPort->sPortParam.bPopulated = OMX_TRUE; openmaxStandPort->bIsFullOfBuffers = OMX_TRUE; tsem_up(openmaxStandPort->pAllocSem); } OMXDBUG(OMXDBUG_VERB, "Out of %s for port %p\n", __func__, openmaxStandPort); return OMX_ErrorNone; } } OMXDBUG(OMXDBUG_ERR, "In %s Error: no available buffers CompName=%s\n", __func__, omx_base_component_Private->name); return OMX_ErrorInsufficientResources; }
/** @brief Called by the standard function. * * It frees the buffer header and in case also the buffer itself, if needed. * When all the buffers are done, the variable bIsEmptyOfBuffers is set to OMX_TRUE */ OMX_ERRORTYPE camera_video_port_FreeBuffer( omx_base_PortType *openmaxStandPort, OMX_U32 nPortIndex, OMX_BUFFERHEADERTYPE *pBuffer) { unsigned int i; OMX_COMPONENTTYPE *omxComponent = openmaxStandPort->standCompContainer; omx_base_component_PrivateType *omx_base_component_Private = (omx_base_component_PrivateType *)omxComponent->pComponentPrivate; omx_base_camera_video_PortType *omx_base_video_Port = (omx_base_camera_video_PortType *)openmaxStandPort; OMXDBUG(OMXDBUG_VERB, "In %s for port %p,%d\n", __func__, openmaxStandPort, (int)nPortIndex); if(nPortIndex != openmaxStandPort->sPortParam.nPortIndex) { return OMX_ErrorBadPortIndex; } if(PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) { return OMX_ErrorBadPortIndex; } //printf("b,,,,1\n"); if(omx_base_component_Private->transientState != OMX_TransStateIdleToLoaded) { if(!openmaxStandPort->bIsTransientToDisabled) { OMXDBUG(OMXDBUG_VERB, "In %s: The port is not allowed to free the buffers\n", __func__); (*(omx_base_component_Private->callbacks->EventHandler)) (omxComponent, omx_base_component_Private->callbackData, OMX_EventError, /* The command was completed */ OMX_ErrorPortUnpopulated, /* The commands was a OMX_CommandStateSet */ nPortIndex, /* The state has been changed in message->messageParam2 */ NULL); } } for(i = 0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++) { if(openmaxStandPort->bBufferStateAllocated[i] & (BUFFER_ASSIGNED | BUFFER_ALLOCATED)) { openmaxStandPort->bIsFullOfBuffers = OMX_FALSE; if(openmaxStandPort->bBufferStateAllocated[i] & BUFFER_ALLOCATED) { if(openmaxStandPort->pInternalBufferStorage[i]->pBuffer) { OMXDBUG(OMXDBUG_VERB, "In %s freeing %i pBuffer=%p\n", __func__, (int)i, openmaxStandPort->pInternalBufferStorage[i]->pBuffer); if(omx_base_video_Port->pBufferHeadAct[i].pConfigParam.bAllocByComp == OMX_TRUE) { ext_phyfree_mem((void *)openmaxStandPort->pInternalBufferStorage[i]->pBuffer, \ (void *)omx_base_video_Port->pBufferHeadAct[i].pConfigParam.VirAddr); omx_base_video_Port->pBufferHeadAct[i].pConfigParam.bAllocByComp = OMX_FALSE; omx_base_video_Port->pBufferHeadAct[i].pBuffHead = NULL; } else { free(openmaxStandPort->pInternalBufferStorage[i]->pBuffer); } openmaxStandPort->pInternalBufferStorage[i]->pBuffer = NULL; omx_base_video_Port->pBufferHeadAct[i].pConfigParam.bUseBufFlag = OMX_FALSE; } } else if(openmaxStandPort->bBufferStateAllocated[i] & BUFFER_ASSIGNED) { // printf("buffer free....????%x\n",pBuffer); if(omx_base_video_Port->pBufferHeadAct[i].pConfigParam.bAllocByComp == OMX_TRUE) { ext_phyfree_mem((void *)omx_base_video_Port->pBufferHeadAct[i].pConfigParam.phyAddr, \ (void *)omx_base_video_Port->pBufferHeadAct[i].pConfigParam.VirAddr); omx_base_video_Port->pBufferHeadAct[i].pConfigParam.bAllocByComp = OMX_FALSE; omx_base_video_Port->pBufferHeadAct[i].pConfigParam.phyAddr = NULL; omx_base_video_Port->pBufferHeadAct[i].pConfigParam.VirAddr = NULL; omx_base_video_Port->pBufferHeadAct[i].pBuffHead = NULL; } omx_base_video_Port->pBufferHeadAct[i].pConfigParam.bUseBufFlag = OMX_FALSE; free(pBuffer); } //printf("b,,,,2\n"); if(openmaxStandPort->bBufferStateAllocated[i] & HEADER_ALLOCATED) { free(openmaxStandPort->pInternalBufferStorage[i]); openmaxStandPort->pInternalBufferStorage[i] = NULL; } openmaxStandPort->bBufferStateAllocated[i] = BUFFER_FREE; openmaxStandPort->nNumAssignedBuffers--; OMXDBUG(OMXDBUG_VERB, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers); if(openmaxStandPort->nNumAssignedBuffers == 0) { if(omx_base_video_Port->pBufferHeadAct) { free(omx_base_video_Port->pBufferHeadAct); omx_base_video_Port->pBufferHeadAct = NULL; printf("Free pBufferHeadAct now\n"); } openmaxStandPort->sPortParam.bPopulated = OMX_FALSE; openmaxStandPort->bIsEmptyOfBuffers = OMX_TRUE; tsem_up(openmaxStandPort->pAllocSem); } OMXDBUG(OMXDBUG_VERB, "Out of %s for port %p\n", __func__, openmaxStandPort); return OMX_ErrorNone; } } OMXDBUG(OMXDBUG_ERR, "Out of %s for port %p with OMX_ErrorInsufficientResources\n", __func__, openmaxStandPort); return OMX_ErrorInsufficientResources; }
/** * Returns Input/Output Buffer to the IL client or Tunneled Component */ OMX_ERRORTYPE videoenc_port_ReturnBufferFunction( omx_base_PortType *openmaxStandPort, OMX_BUFFERHEADERTYPE *pBuffer) { int errQue; OMX_ERRORTYPE eError = OMX_ErrorNone; omx_base_component_PrivateType *omx_base_component_Private = openmaxStandPort->standCompContainer->pComponentPrivate; omx_videoenc_PortType *omx_videoenc_Port = (omx_videoenc_PortType *)openmaxStandPort; queue_t *pQueue = omx_videoenc_Port->pBufferQueue; tsem_t *pSem = omx_videoenc_Port->pBufferSem; OMX_VCE_Buffers_List *pBuffersMng_List= &(omx_videoenc_Port->BuffersMng_List); DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, omx_videoenc_Port); OMX_BUFFERHEADERTYPE *pBuffer_ACTEXT = (OMX_BUFFERHEADERTYPE *)pBuffer; if( omx_videoenc_Port->sPortParam.eDir == OMX_DirOutput ) { eError = ReturnBuffer_BuffersMng(pBuffersMng_List, pBuffer_ACTEXT, omx_videoenc_Port->bIsStoreMediaData); if(eError != OMX_ErrorNone) { DEBUG(DEB_LEV_ERR, "err!ReturnBuffer_BuffersMng fail!%s,%d\n",__FILE__,__LINE__); return eError; } } #ifdef enable_gralloc if(pBuffer->nFilledLen == 0 && ((pBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) ) { DEBUG(DEB_LEV_ERR, "ReturnBufferFunction,input buffer is eos now!"); } else { eError = UnLock_VirAddr_BuffersMng(pBuffersMng_List, pBuffer_ACTEXT, omx_videoenc_Port->bIsStoreMediaData); if(eError != OMX_ErrorNone) { DEBUG(DEB_LEV_ERR, "err!UnLock_VirAddr_BuffersMng fail!%s,%d\n", __FILE__, __LINE__); return eError; } } #endif if (PORT_IS_TUNNELED(omx_videoenc_Port) && ! PORT_IS_BUFFER_SUPPLIER(omx_videoenc_Port)) { if (omx_videoenc_Port->sPortParam.eDir == OMX_DirInput) { pBuffer->nOutputPortIndex = omx_videoenc_Port->nTunneledPort; pBuffer->nInputPortIndex = omx_videoenc_Port->sPortParam.nPortIndex; eError = ((OMX_COMPONENTTYPE *)(omx_videoenc_Port->hTunneledComponent))->FillThisBuffer(omx_videoenc_Port->hTunneledComponent, pBuffer); if(eError != OMX_ErrorNone) { DEBUG(DEB_LEV_ERR, "In %s eError %08x in FillThis Buffer from Component %s Non-Supplier\n", __func__, eError,omx_base_component_Private->name); } } else { pBuffer->nInputPortIndex = omx_videoenc_Port->nTunneledPort; pBuffer->nOutputPortIndex = omx_videoenc_Port->sPortParam.nPortIndex; eError = ((OMX_COMPONENTTYPE *)(omx_videoenc_Port->hTunneledComponent))->EmptyThisBuffer(omx_videoenc_Port->hTunneledComponent, pBuffer); if(eError != OMX_ErrorNone) { DEBUG(DEB_LEV_ERR, "In %s eError %08x in EmptyThis Buffer from Component %s Non-Supplier\n", __func__, eError, omx_base_component_Private->name); } } } else if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(omx_videoenc_Port) && !PORT_IS_BEING_FLUSHED(omx_videoenc_Port)) { if (omx_videoenc_Port->sPortParam.eDir == OMX_DirInput) { eError = ((OMX_COMPONENTTYPE *)(omx_videoenc_Port->hTunneledComponent))->FillThisBuffer(omx_videoenc_Port->hTunneledComponent, pBuffer); if(eError != OMX_ErrorNone) { DEBUG(DEB_LEV_FULL_SEQ, "In %s eError %08x in FillThis Buffer from Component %s Supplier\n", __func__, eError,omx_base_component_Private->name); /*If Error Occured then queue the buffer*/ errQue = queue(pQueue, pBuffer); if (errQue) { /* /TODO the queue is full. This can be handled in a fine way with * some retrials, or other checking. For the moment this is a critical error * and simply causes the failure of this call */ return OMX_ErrorInsufficientResources; } tsem_up(pSem); } } else { eError = ((OMX_COMPONENTTYPE *)(omx_videoenc_Port->hTunneledComponent))->EmptyThisBuffer(omx_videoenc_Port->hTunneledComponent, pBuffer); if(eError != OMX_ErrorNone) { DEBUG(DEB_LEV_FULL_SEQ, "In %s eError %08x in EmptyThis Buffer from Component %s Supplier\n", __func__, eError,omx_base_component_Private->name); /*If Error Occured then queue the buffer*/ errQue = queue(pQueue, pBuffer); if (errQue) { /* /TODO the queue is full. This can be handled in a fine way with * some retrials, or other checking. For the moment this is a critical error * and simply causes the failure of this call */ return OMX_ErrorInsufficientResources; } tsem_up(pSem); } } } else if (!PORT_IS_TUNNELED(omx_videoenc_Port)) { //here (*(omx_videoenc_Port->BufferProcessedCallback))( omx_videoenc_Port->standCompContainer, omx_base_component_Private->callbackData, pBuffer); } else { errQue = queue(pQueue, pBuffer); if (errQue) { /* /TODO the queue is full. This can be handled in a fine way with * some retrials, or other checking. For the moment this is a critical error * and simply causes the failure of this call */ return OMX_ErrorInsufficientResources; } omx_videoenc_Port->nNumBufferFlushed++; } DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, omx_videoenc_Port); return OMX_ErrorNone; }
/** @brief the entry point for sending buffers to the port * * This function can be called by the EmptyThisBuffer or FillThisBuffer. It depends on * the nature of the port, that can be an input or output port. */ OMX_ERRORTYPE videoenc_port_SendBufferFunction( omx_base_PortType *openmaxStandPort, OMX_BUFFERHEADERTYPE *pBuffer) { int errQue; OMX_U32 portIndex; OMX_ERRORTYPE err = OMX_ErrorNone; OMX_COMPONENTTYPE *omxComponent = openmaxStandPort->standCompContainer; omx_videoenc_PortType *omx_videoenc_Port = (omx_videoenc_PortType *)openmaxStandPort; omx_base_component_PrivateType *omx_base_component_Private = (omx_base_component_PrivateType *)omxComponent->pComponentPrivate; OMX_VCE_Buffers_List *pBuffersMng_List= &(omx_videoenc_Port->BuffersMng_List); DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, omx_videoenc_Port); #if NO_GST_OMX_PATCH unsigned int i; #endif portIndex = (omx_videoenc_Port->sPortParam.eDir == OMX_DirInput) ? pBuffer->nInputPortIndex : pBuffer->nOutputPortIndex; DEBUG(DEB_LEV_FUNCTION_NAME, "In %s portIndex %d\n", __func__, portIndex); if (portIndex != omx_videoenc_Port->sPortParam.nPortIndex) { DEBUG(DEB_LEV_ERR, "In %s: wrong port for this operation portIndex=%d port->portIndex=%d\n", __func__, (int)portIndex, (int)omx_videoenc_Port->sPortParam.nPortIndex); return OMX_ErrorBadPortIndex; } if(omx_base_component_Private->state == OMX_StateInvalid) { DEBUG(DEB_LEV_ERR, "In %s: we are in OMX_StateInvalid\n", __func__); return OMX_ErrorInvalidState; } if(omx_base_component_Private->state != OMX_StateExecuting && omx_base_component_Private->state != OMX_StatePause && omx_base_component_Private->state != OMX_StateIdle) { DEBUG(DEB_LEV_ERR, "In %s: we are not in executing/paused/idle state, but in %d\n", __func__, omx_base_component_Private->state); return OMX_ErrorIncorrectStateOperation; } if (!PORT_IS_ENABLED(omx_videoenc_Port) || (PORT_IS_BEING_DISABLED(omx_videoenc_Port) && !PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(omx_videoenc_Port)) || ((omx_base_component_Private->transientState == OMX_TransStateExecutingToIdle || omx_base_component_Private->transientState == OMX_TransStatePauseToIdle) && (PORT_IS_TUNNELED(omx_videoenc_Port) && !PORT_IS_BUFFER_SUPPLIER(omx_videoenc_Port)))) { DEBUG(DEB_LEV_ERR, "In %s: Port %d is disabled comp = %s \n", __func__, (int)portIndex, omx_base_component_Private->name); return OMX_ErrorIncorrectStateOperation; } /* Temporarily disable this check for gst-openmax */ #if NO_GST_OMX_PATCH { OMX_BOOL foundBuffer = OMX_FALSE; if(pBuffer!=NULL && pBuffer->pBuffer!=NULL) { for(i=0; i < omx_videoenc_Port->sPortParam.nBufferCountActual; i++) { if (pBuffer->pBuffer == omx_videoenc_Port->pInternalBufferStorage[i]->pBuffer) { foundBuffer = OMX_TRUE; break; } } } if (!foundBuffer) { return OMX_ErrorBadParameter; } } #endif if ((err = checkHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE))) != OMX_ErrorNone) { DEBUG(DEB_LEV_ERR, "In %s: received wrong buffer header on input port\n", __func__); return err; } /* And notify the buffer management thread we have a fresh new buffer to manage */ if(!PORT_IS_BEING_FLUSHED(omx_videoenc_Port) && \ !(PORT_IS_BEING_DISABLED(omx_videoenc_Port) && PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(omx_videoenc_Port))) { //here if(omx_videoenc_Port->bIsStoreMediaData == OMX_TRUE) { if((*(OMX_U32 *)pBuffer->pBuffer != kMetadataBufferTypeCameraSource_act) && \ (*(OMX_U32 *)pBuffer->pBuffer != kMetadataBufferTypeGrallocSource_act)) { DEBUG(DEB_LEV_ERR, "Warning!in StoreMediaData mode,but the buffer (%x) is not kMetadataBufferTypeCameraSource_act!\n", (int)*(OMX_U32 *)pBuffer->pBuffer); } } if(omx_videoenc_Port->ringbuffer == OMX_TRUE && omx_videoenc_Port->sPortParam.nPortIndex == OMX_BASE_FILTER_OUTPUTPORT_INDEX) { err = Free_UseRingBuffer_BuffersMng(&omx_videoenc_Port->BuffersMng_List,omx_videoenc_Port->bufferpool,pBuffer, omx_videoenc_Port->sPortParam.nBufferSize); if( err != OMX_ErrorNone) { DEBUG(DEB_LEV_ERR, "err!In %s: SendBuffer_BuffersMng\n", __func__); return err; } } else { err = SendBuffer_BuffersMng(pBuffersMng_List,pBuffer,omx_videoenc_Port->bIsStoreMediaData,omx_videoenc_Port->sPortParam.eDir); if( err != OMX_ErrorNone) { DEBUG(DEB_LEV_ERR, "err!In %s: SendBuffer_BuffersMng\n", __func__); return err; } } errQue = queue(omx_videoenc_Port->pBufferQueue, pBuffer); if (errQue) { /* /TODO the queue is full. This can be handled in a fine way with * some retrials, or other checking. For the moment this is a critical error * and simply causes the failure of this call */ return OMX_ErrorInsufficientResources; } tsem_up(omx_videoenc_Port->pBufferSem); DEBUG(DEB_LEV_PARAMS, "In %s Signalling bMgmtSem Port Index=%d\n", __func__, (int)portIndex); tsem_up(omx_base_component_Private->bMgmtSem); } else if(PORT_IS_BUFFER_SUPPLIER(omx_videoenc_Port)) { DEBUG(DEB_LEV_FULL_SEQ, "In %s: Comp %s received io:%d buffer\n", __func__, omx_base_component_Private->name, (int)omx_videoenc_Port->sPortParam.nPortIndex); errQue = queue(omx_videoenc_Port->pBufferQueue, pBuffer); if (errQue) { /* /TODO the queue is full. This can be handled in a fine way with * some retrials, or other checking. For the moment this is a critical error * and simply causes the failure of this call */ return OMX_ErrorInsufficientResources; } tsem_up(omx_videoenc_Port->pBufferSem); } else { // If port being flushed and not tunneled then return error DEBUG(DEB_LEV_FULL_SEQ, "In %s \n", __func__); return OMX_ErrorIncorrectStateOperation; } DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, omx_videoenc_Port); return OMX_ErrorNone; }
/** @brief Called by the standard function. * * It frees the buffer header and in case also the buffer itself, if needed. * When all the buffers are done, the variable bIsEmptyOfBuffers is set to OMX_TRUE */ OMX_ERRORTYPE videoenc_port_FreeBuffer( omx_base_PortType *openmaxStandPort, OMX_U32 nPortIndex, OMX_BUFFERHEADERTYPE *pBuffer) { unsigned int i; OMX_ERRORTYPE err = OMX_ErrorNone; OMX_COMPONENTTYPE *omxComponent = openmaxStandPort->standCompContainer; omx_videoenc_PortType *omx_videoenc_Port = (omx_videoenc_PortType *)openmaxStandPort; omx_base_component_PrivateType *omx_base_component_Private = (omx_base_component_PrivateType *)omxComponent->pComponentPrivate; OMX_BUFFERHEADERTYPE *pBufferStorage_ACTEXT = NULL; OMX_VCE_Buffers_List *pBuffersMng_List= &(omx_videoenc_Port->BuffersMng_List); DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, omx_videoenc_Port); if (nPortIndex != omx_videoenc_Port->sPortParam.nPortIndex) { return OMX_ErrorBadPortIndex; } if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(omx_videoenc_Port)) { return OMX_ErrorBadPortIndex; } DEBUG(DEB_LEV_SIMPLE_SEQ, "cur state %x,%x\n", omx_base_component_Private->transientState, omx_videoenc_Port->bIsTransientToDisabled); if (omx_base_component_Private->transientState != OMX_TransStateIdleToLoaded) { if (!omx_videoenc_Port->bIsTransientToDisabled) { DEBUG(DEB_LEV_FULL_SEQ, "In %s: The port is not allowed to free the buffers\n", __func__); (*(omx_base_component_Private->callbacks->EventHandler)) (omxComponent, omx_base_component_Private->callbackData, OMX_EventError, OMX_ErrorPortUnpopulated, nPortIndex, NULL); } } for(i=0; i < omx_videoenc_Port->sPortParam.nBufferCountActual; i++) { pBufferStorage_ACTEXT = (OMX_BUFFERHEADERTYPE *)(omx_videoenc_Port->pInternalBufferStorage[i]); if (omx_videoenc_Port->bBufferStateAllocated[i] & (BUFFER_ASSIGNED | BUFFER_ALLOCATED)) { omx_videoenc_Port->bIsFullOfBuffers = OMX_FALSE; if((omx_videoenc_Port->bBufferStateAllocated[i] & BUFFER_ALLOCATED)) { if(omx_videoenc_Port->pInternalBufferStorage[i] != pBuffer) { DEBUG(DEB_LEV_PARAMS,"ringbuf %d,%p,%p\n", omx_videoenc_Port->ringbuffer, omx_videoenc_Port->pInternalBufferStorage[i], pBuffer); continue; } } if(omx_videoenc_Port->ringbuffer == OMX_FALSE) { if (omx_videoenc_Port->bBufferStateAllocated[i] & BUFFER_ALLOCATED) { err = Free_AllocateBuffer_BuffersMng(pBuffersMng_List, pBufferStorage_ACTEXT, omx_videoenc_Port->bIsStoreMediaData); if(err != OMX_ErrorNone) { DEBUG(DEB_LEV_ERR,"err!Free_AllocateBuffer_BuffersMng fail!%s,%d\n", __FILE__, __LINE__); return err; } } else if (omx_videoenc_Port->bBufferStateAllocated[i] & BUFFER_ASSIGNED) { err = Free_UseBuffer_BuffersMng(pBuffersMng_List, pBufferStorage_ACTEXT, omx_videoenc_Port->bIsStoreMediaData); if(err != OMX_ErrorNone) { DEBUG(DEB_LEV_ERR,"err!Free_UseBuffer_BuffersMng fail!%s,%d\n",__FILE__, __LINE__); return err; } if(pBuffer) free(pBuffer); } } if(omx_videoenc_Port->bBufferStateAllocated[i] & HEADER_ALLOCATED) { free(omx_videoenc_Port->pInternalBufferStorage[i]); omx_videoenc_Port->pInternalBufferStorage[i] = NULL; } omx_videoenc_Port->bBufferStateAllocated[i] = BUFFER_FREE; omx_videoenc_Port->nNumAssignedBuffers--; DEBUG(DEB_LEV_PARAMS, "omx_videoenc_Port->nNumAssignedBuffers %i\n", (int)omx_videoenc_Port->nNumAssignedBuffers); if (omx_videoenc_Port->nNumAssignedBuffers == 0) { if(omx_videoenc_Port->bIsStoreMediaData == OMX_TRUE) { err = Clear_StoreMedia_BuffersMng(pBuffersMng_List); if(err != OMX_ErrorNone) { DEBUG(DEB_LEV_ERR,"err!Clear_StoreMedia_BuffersMng fail!%s,%d\n", __FILE__, __LINE__); return err; } } if(omx_videoenc_Port->ringbuffer == OMX_TRUE && omx_videoenc_Port->bufferpool) { pool_dispose(omx_videoenc_Port->bufferpool); omx_videoenc_Port->bufferpool = NULL; } omx_videoenc_Port->sPortParam.bPopulated = OMX_FALSE; omx_videoenc_Port->bIsEmptyOfBuffers = OMX_TRUE; DEBUG(DEB_LEV_PARAMS, "pAllocSem!%s,%d,idx:%d,semval:%d\n", __func__, __LINE__, omx_videoenc_Port->sPortParam.nPortIndex, omx_videoenc_Port->pAllocSem->semval); tsem_up(omx_videoenc_Port->pAllocSem); } DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, omx_videoenc_Port); return OMX_ErrorNone; } } DEBUG(DEB_LEV_ERR, "Out of %s for port %p with OMX_ErrorInsufficientResources\n", __func__, omx_videoenc_Port); return OMX_ErrorInsufficientResources; }
/** @brief Called by the standard use buffer, it implements a base functionality. * * This function can be overriden if the use buffer implicate more complicated operations. * The parameters are the same as the standard function, except for the handle of the port * instead of the handler of the component. * When the buffers needed by this port are all assigned or allocated, the variable * bIsFullOfBuffers becomes equal to OMX_TRUE */ OMX_ERRORTYPE videoenc_port_UseBuffer( omx_base_PortType *openmaxStandPort, OMX_BUFFERHEADERTYPE **ppBufferHdr, OMX_U32 nPortIndex, OMX_PTR pAppPrivate, OMX_U32 nSizeBytes, OMX_U8 *pBuffer) { unsigned int i; OMX_ERRORTYPE err = OMX_ErrorNone; OMX_BUFFERHEADERTYPE *returnBufferHeader; OMX_COMPONENTTYPE *omxComponent = openmaxStandPort->standCompContainer; omx_videoenc_PortType *omx_videoenc_Port = (omx_videoenc_PortType *)openmaxStandPort; omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType *)omxComponent->pComponentPrivate; OMX_BUFFERHEADERTYPE *pBufferStorage_ACTEXT = NULL; OMX_VCE_Buffers_List *pBuffersMng_List= &(omx_videoenc_Port->BuffersMng_List); DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, omx_videoenc_Port); if (nPortIndex != omx_videoenc_Port->sPortParam.nPortIndex) { return OMX_ErrorBadPortIndex; } if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(omx_videoenc_Port)) { return OMX_ErrorBadPortIndex; } if (omx_base_component_Private->transientState != OMX_TransStateLoadedToIdle) { if (!omx_videoenc_Port->bIsTransientToEnabled) { DEBUG(DEB_LEV_ERR, "In %s: The port of Comp %s is not allowed to receive buffers\n", __func__, omx_base_component_Private->name); return OMX_ErrorIncorrectStateTransition; } } if(omx_videoenc_Port->bIsStoreMediaData == OMX_FALSE) { if(nSizeBytes < omx_videoenc_Port->sPortParam.nBufferSize) { DEBUG(DEB_LEV_ERR, "In %s: Port %d Given Buffer Size %u is less than Minimum Buffer Size %u\n", __func__, (int)nPortIndex, (int)nSizeBytes, (int)omx_videoenc_Port->sPortParam.nBufferSize); return OMX_ErrorBadParameter; } } else { if(nSizeBytes < sizeof(video_metadata_t)) { DEBUG(DEB_LEV_ERR,"err!Bad buffer sizes on StoreMediaData type%d\n", nSizeBytes); return OMX_ErrorBadParameter; } } for(i=0; i < omx_videoenc_Port->sPortParam.nBufferCountActual; i++) { if (omx_videoenc_Port->bBufferStateAllocated[i] == BUFFER_FREE) { omx_videoenc_Port->pInternalBufferStorage[i] = calloc(1, sizeof(OMX_BUFFERHEADERTYPE)); if (!omx_videoenc_Port->pInternalBufferStorage[i]) { return OMX_ErrorInsufficientResources; } omx_videoenc_Port->bIsEmptyOfBuffers = OMX_FALSE; pBufferStorage_ACTEXT = (OMX_BUFFERHEADERTYPE *)(omx_videoenc_Port->pInternalBufferStorage[i]); setHeader(pBufferStorage_ACTEXT, sizeof(OMX_BUFFERHEADERTYPE)); pBufferStorage_ACTEXT->nAllocLen = nSizeBytes; pBufferStorage_ACTEXT->pPlatformPrivate = omx_videoenc_Port; pBufferStorage_ACTEXT->pAppPrivate = pAppPrivate; omx_videoenc_Port->bBufferStateAllocated[i] = BUFFER_ASSIGNED; omx_videoenc_Port->bBufferStateAllocated[i] |= HEADER_ALLOCATED; err = Add_UseBuffer_BuffersMng(pBuffersMng_List, pBufferStorage_ACTEXT, omx_videoenc_Port->bIsStoreMediaData, nSizeBytes, pBuffer); if( err != OMX_ErrorNone) { DEBUG(DEB_LEV_ERR,"err!Add_UseBuffer_BuffersMng fail!%s,%d\n", __FILE__, __LINE__); free(omx_videoenc_Port->pInternalBufferStorage[i]); omx_videoenc_Port->pInternalBufferStorage[i] = NULL; return err; } returnBufferHeader = calloc(1, sizeof(OMX_BUFFERHEADERTYPE)); if (!returnBufferHeader) { return OMX_ErrorInsufficientResources; } setHeader(returnBufferHeader, sizeof(OMX_BUFFERHEADERTYPE)); returnBufferHeader->pBuffer = pBuffer; returnBufferHeader->nAllocLen = nSizeBytes; returnBufferHeader->pPlatformPrivate = omx_videoenc_Port; returnBufferHeader->pAppPrivate = pAppPrivate; if (omx_videoenc_Port->sPortParam.eDir == OMX_DirInput) { pBufferStorage_ACTEXT->nInputPortIndex = omx_videoenc_Port->sPortParam.nPortIndex; returnBufferHeader->nInputPortIndex = omx_videoenc_Port->sPortParam.nPortIndex; } else { pBufferStorage_ACTEXT->nOutputPortIndex = omx_videoenc_Port->sPortParam.nPortIndex; returnBufferHeader->nOutputPortIndex = omx_videoenc_Port->sPortParam.nPortIndex; } *ppBufferHdr = returnBufferHeader; omx_videoenc_Port->nNumAssignedBuffers++; DEBUG(DEB_LEV_PARAMS, "omx_videoenc_Port->nNumAssignedBuffers %d,%d\n", omx_videoenc_Port->sPortParam.nBufferCountActual, (int)omx_videoenc_Port->nNumAssignedBuffers); if (omx_videoenc_Port->sPortParam.nBufferCountActual == omx_videoenc_Port->nNumAssignedBuffers) { omx_videoenc_Port->sPortParam.bPopulated = OMX_TRUE; omx_videoenc_Port->bIsFullOfBuffers = OMX_TRUE; DEBUG(DEB_LEV_PARAMS, "pAllocSem!%s,%d,idx:%d,semval:%d\n", __func__, __LINE__, omx_videoenc_Port->sPortParam.nPortIndex, omx_videoenc_Port->pAllocSem->semval); tsem_up(omx_videoenc_Port->pAllocSem); } DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, omx_videoenc_Port); return OMX_ErrorNone; } } DEBUG(DEB_LEV_ERR, "In %s Error: no available buffers CompName=%s\n", __func__, omx_base_component_Private->name); return OMX_ErrorInsufficientResources; }
/** @brief Called by the standard allocate buffer, it implements a base functionality. * * This function can be overriden if the allocation of the buffer is not a simply alloc call. * The parameters are the same as the standard function, except for the handle of the port * instead of the handler of the component * When the buffers needed by this port are all assigned or allocated, the variable * bIsFullOfBuffers becomes equal to OMX_TRUE */ OMX_ERRORTYPE videoenc_port_AllocateBuffer( omx_base_PortType *openmaxStandPort, OMX_BUFFERHEADERTYPE **pBuffer, OMX_U32 nPortIndex, OMX_PTR pAppPrivate, OMX_U32 nSizeBytes) { unsigned int i; OMX_ERRORTYPE err = OMX_ErrorNone; OMX_COMPONENTTYPE *omxComponent = openmaxStandPort->standCompContainer; omx_videoenc_PortType *omx_videoenc_Port = (omx_videoenc_PortType *)openmaxStandPort; omx_base_component_PrivateType *omx_base_component_Private = (omx_base_component_PrivateType *)omxComponent->pComponentPrivate; OMX_BUFFERHEADERTYPE *pBufferStorage_ACTEXT = NULL; OMX_VCE_Buffers_List *pBuffersMng_List= &(omx_videoenc_Port->BuffersMng_List); DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, omx_videoenc_Port); if (nPortIndex != omx_videoenc_Port->sPortParam.nPortIndex) { return OMX_ErrorBadPortIndex; } if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(omx_videoenc_Port)) { return OMX_ErrorBadPortIndex; } if (omx_base_component_Private->transientState != OMX_TransStateLoadedToIdle) { if (!omx_videoenc_Port->bIsTransientToEnabled) { DEBUG(DEB_LEV_ERR, "In %s: The port is not allowed to receive buffers\n", __func__); return OMX_ErrorIncorrectStateTransition; } } if(nSizeBytes < omx_videoenc_Port->sPortParam.nBufferSize) { DEBUG(DEB_LEV_ERR, "In %s: Requested Buffer Size %d is less than Minimum Buffer Size %d\n", __func__, nSizeBytes, omx_videoenc_Port->sPortParam.nBufferSize); return OMX_ErrorIncorrectStateTransition; } if(omx_videoenc_Port->ringbuffer == OMX_TRUE && nPortIndex == OMX_BASE_FILTER_OUTPUTPORT_INDEX) { /* open ringbuffer pool */ int buffsize = omx_videoenc_Port->ringbuf_framesize * omx_videoenc_Port->sPortParam.nBufferCountActual; if(omx_videoenc_Port->bufferpool != NULL) { if(buffsize > get_poolsize(omx_videoenc_Port->bufferpool)) { pool_dispose(omx_videoenc_Port->bufferpool); omx_videoenc_Port->bufferpool = NULL; if(pool_open(buffsize, &omx_videoenc_Port->bufferpool)) { DEBUG(DEB_LEV_ERR, "In %s: The port is not allowed to receive buffers %x\n", __func__, buffsize); return OMX_ErrorInsufficientResources; } } } else { if( pool_open(buffsize, &omx_videoenc_Port->bufferpool) ) { DEBUG(DEB_LEV_ERR, "In %s: The port is not allowed to receive buffers %x\n", __func__, buffsize); return OMX_ErrorInsufficientResources; } } } for(i=0; i < omx_videoenc_Port->sPortParam.nBufferCountActual; i++) { if (omx_videoenc_Port->bBufferStateAllocated[i] == BUFFER_FREE) { omx_videoenc_Port->pInternalBufferStorage[i] = (OMX_BUFFERHEADERTYPE *)calloc(1, sizeof(OMX_BUFFERHEADERTYPE)); if (!omx_videoenc_Port->pInternalBufferStorage[i]) { return OMX_ErrorInsufficientResources; } setHeader(omx_videoenc_Port->pInternalBufferStorage[i], sizeof(OMX_BUFFERHEADERTYPE)); /* allocate the buffer */ pBufferStorage_ACTEXT = (OMX_BUFFERHEADERTYPE *)(omx_videoenc_Port->pInternalBufferStorage[i]); pBufferStorage_ACTEXT->nAllocLen = nSizeBytes; pBufferStorage_ACTEXT->pPlatformPrivate = omx_videoenc_Port; pBufferStorage_ACTEXT->pAppPrivate = pAppPrivate; if(nPortIndex == OMX_BASE_FILTER_OUTPUTPORT_INDEX && omx_videoenc_Port->ringbuffer == OMX_TRUE) { pBufferStorage_ACTEXT->pBuffer = get_poolbase(omx_videoenc_Port->bufferpool); if(pBufferStorage_ACTEXT->pBuffer==NULL) { DEBUG(DEB_LEV_ERR, "err!get_poolbase is NULL!\n"); free(pBufferStorage_ACTEXT); omx_videoenc_Port->pInternalBufferStorage[i] = NULL; return OMX_ErrorInsufficientResources; } } else { DEBUG(DEB_LEV_PARAMS, "nSizeBytes:%d\n", nSizeBytes); err = Add_AllocateBuffer_BuffersMng(pBuffersMng_List, pBufferStorage_ACTEXT, omx_videoenc_Port->bIsStoreMediaData, nSizeBytes); if( err != OMX_ErrorNone) { DEBUG(DEB_LEV_ERR,"err!Add_AllocateBuffer_BuffersMng fail!%s,%d\n", __FILE__, __LINE__); free(omx_videoenc_Port->pInternalBufferStorage[i]); omx_videoenc_Port->pInternalBufferStorage[i] = NULL; return err; } } *pBuffer = (OMX_BUFFERHEADERTYPE *)pBufferStorage_ACTEXT; omx_videoenc_Port->bBufferStateAllocated[i] = BUFFER_ALLOCATED; omx_videoenc_Port->bBufferStateAllocated[i] |= HEADER_ALLOCATED; if (omx_videoenc_Port->sPortParam.eDir == OMX_DirInput) { pBufferStorage_ACTEXT->nInputPortIndex = omx_videoenc_Port->sPortParam.nPortIndex; } else { pBufferStorage_ACTEXT->nOutputPortIndex = omx_videoenc_Port->sPortParam.nPortIndex; } omx_videoenc_Port->nNumAssignedBuffers++; DEBUG(DEB_LEV_PARAMS, "omx_videoenc_Port->nNumAssignedBuffers %i\n", (int)omx_videoenc_Port->nNumAssignedBuffers); if (omx_videoenc_Port->sPortParam.nBufferCountActual == omx_videoenc_Port->nNumAssignedBuffers) { omx_videoenc_Port->sPortParam.bPopulated = OMX_TRUE; omx_videoenc_Port->bIsFullOfBuffers = OMX_TRUE; DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s nPortIndex=%d\n", __func__, (int)nPortIndex); DEBUG(DEB_LEV_PARAMS, "pAllocSem!%s,%d,idx:%d,semval:%d\n", __func__, __LINE__, omx_videoenc_Port->sPortParam.nPortIndex, omx_videoenc_Port->pAllocSem->semval); tsem_up(omx_videoenc_Port->pAllocSem); } DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, omx_videoenc_Port); return OMX_ErrorNone; } } DEBUG(DEB_LEV_ERR, "Out of %s for port %p. Error: no available buffers\n", __func__, omx_videoenc_Port); return OMX_ErrorInsufficientResources; }