コード例 #1
0
/**=========================================================================**/
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;
}
コード例 #2
0
/** @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;
}
コード例 #3
0
/** @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;
}
コード例 #4
0
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;
}
コード例 #5
0
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;
}
コード例 #6
0
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;
}
コード例 #7
0
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;
}
コード例 #8
0
/** @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;
}
コード例 #9
0
/** @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;
}
コード例 #10
0
/** @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;
}
コード例 #11
0
/** @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;
}
コード例 #12
0
/**
 * 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;
}
コード例 #13
0
/** @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;
}
コード例 #14
0
/** @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;
}
コード例 #15
0
/** @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;
}
コード例 #16
0
/** @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;
}