OpenMAXBellagio 0.9.3
omx_base_clock_port.c
Go to the documentation of this file.
00001 
00026 #include <string.h>
00027 #include <unistd.h>
00028 #include <omxcore.h>
00029 #include <OMX_Core.h>
00030 #include <OMX_Component.h>
00031 #include "omx_base_component.h"
00032 #include "omx_base_clock_port.h"
00033 
00050 OMX_ERRORTYPE base_clock_port_Constructor(OMX_COMPONENTTYPE *openmaxStandComp,omx_base_PortType **openmaxStandPort,OMX_U32 nPortIndex, OMX_BOOL isInput) {
00051     OMX_ERRORTYPE err;
00052   omx_base_clock_PortType *omx_base_clock_Port;
00053 
00054   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s of component %p\n", __func__, openmaxStandComp);
00055   if (!(*openmaxStandPort)) {
00056     *openmaxStandPort = calloc(1,sizeof (omx_base_clock_PortType));
00057   }
00058 
00059   if (!(*openmaxStandPort)) {
00060     return OMX_ErrorInsufficientResources;
00061   }
00062 
00063   err = base_port_Constructor(openmaxStandComp,openmaxStandPort,nPortIndex, isInput);
00064   if (err != OMX_ErrorNone) {
00065       DEBUG(DEB_LEV_ERR, "Base port constructor failed in %s\n", __func__);
00066       return err;
00067   }
00068   omx_base_clock_Port = (omx_base_clock_PortType *)*openmaxStandPort;
00069 
00070   setHeader(&omx_base_clock_Port->sOtherParam, sizeof(OMX_OTHER_PARAM_PORTFORMATTYPE));
00071   omx_base_clock_Port->sOtherParam.nPortIndex = nPortIndex;
00072   omx_base_clock_Port->sOtherParam.nIndex = 0;
00073   omx_base_clock_Port->sOtherParam.eFormat = OMX_OTHER_FormatTime;
00074 
00075   omx_base_clock_Port->sPortParam.eDomain              = OMX_PortDomainOther;
00076   omx_base_clock_Port->sPortParam.format.other.eFormat = OMX_OTHER_FormatTime;
00077   omx_base_clock_Port->sPortParam.nBufferSize          = sizeof(OMX_TIME_MEDIATIMETYPE) ;
00078   omx_base_clock_Port->sPortParam.nBufferCountActual   = 1;
00079   omx_base_clock_Port->sPortParam.nBufferCountMin      = 1;
00080   omx_base_clock_Port->sPortParam.format.other.eFormat = OMX_OTHER_FormatTime;
00081 
00082   setHeader(&omx_base_clock_Port->sTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE));
00083   omx_base_clock_Port->sTimeStamp.nPortIndex = nPortIndex;
00084   omx_base_clock_Port->sTimeStamp.nTimestamp = 0x00;
00085 
00086 
00087   setHeader(&omx_base_clock_Port->sMediaTime, sizeof(OMX_TIME_MEDIATIMETYPE));
00088   omx_base_clock_Port->sMediaTime.nClientPrivate = 0;
00089   omx_base_clock_Port->sMediaTime.nOffset = 0x0;
00090   omx_base_clock_Port->sMediaTime.xScale = 1;
00091 
00092   setHeader(&omx_base_clock_Port->sMediaTimeRequest, sizeof(OMX_TIME_MEDIATIMETYPE));
00093   omx_base_clock_Port->sMediaTimeRequest.nPortIndex = nPortIndex;
00094   omx_base_clock_Port->sMediaTimeRequest.pClientPrivate = NULL;
00095   omx_base_clock_Port->sMediaTimeRequest.nOffset = 0x0;
00096 
00097   omx_base_clock_Port->Port_SendBufferFunction = &base_clock_port_SendBufferFunction;
00098   omx_base_clock_Port->PortDestructor = &base_clock_port_Destructor;
00099 
00100   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s of component %p\n", __func__, openmaxStandComp);
00101   return OMX_ErrorNone;
00102 }
00103 
00116 OMX_ERRORTYPE base_clock_port_Destructor(omx_base_PortType *openmaxStandPort){
00117     OMX_ERRORTYPE err;
00118     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s of component %p\n", __func__, openmaxStandPort->standCompContainer);
00119     err = base_port_Destructor(openmaxStandPort);
00120     if (err != OMX_ErrorNone) {
00121         DEBUG(DEB_LEV_ERR, "Base port destructor failed in %s\n", __func__);
00122         return err;
00123     }
00124     DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s of component %p\n", __func__, openmaxStandPort->standCompContainer);
00125     return OMX_ErrorNone;
00126 }
00127 
00133 OMX_ERRORTYPE base_clock_port_SendBufferFunction(
00134   omx_base_PortType *openmaxStandPort,
00135   OMX_BUFFERHEADERTYPE* pBuffer) {
00136 
00137   OMX_ERRORTYPE err;
00138   int           errQue;
00139   OMX_U32 portIndex;
00140   OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer;
00141   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate;
00142   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s of component %p\n", __func__, omxComponent);
00143 #if NO_GST_OMX_PATCH
00144   unsigned int i;
00145 #endif
00146   portIndex = (openmaxStandPort->sPortParam.eDir == OMX_DirInput)?pBuffer->nInputPortIndex:pBuffer->nOutputPortIndex;
00147   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s portIndex %lu\n", __func__, portIndex);
00148 
00149   if (portIndex != openmaxStandPort->sPortParam.nPortIndex) {
00150     DEBUG(DEB_LEV_ERR, "In %s: wrong port for this operation portIndex=%d port->portIndex=%d\n", __func__, (int)portIndex, (int)openmaxStandPort->sPortParam.nPortIndex);
00151     return OMX_ErrorBadPortIndex;
00152   }
00153 
00154   if(omx_base_component_Private->state == OMX_StateInvalid) {
00155     DEBUG(DEB_LEV_ERR, "In %s: we are in OMX_StateInvalid\n", __func__);
00156     return OMX_ErrorInvalidState;
00157   }
00158 
00159   if(omx_base_component_Private->state != OMX_StateExecuting &&
00160     omx_base_component_Private->state != OMX_StatePause &&
00161     omx_base_component_Private->state != OMX_StateIdle) {
00162     DEBUG(DEB_LEV_ERR, "In %s: we are not in executing/paused/idle state, but in %d\n", __func__, omx_base_component_Private->state);
00163     return OMX_ErrorIncorrectStateOperation;
00164   }
00165   if (!PORT_IS_ENABLED(openmaxStandPort) || (PORT_IS_BEING_DISABLED(openmaxStandPort) && !PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) ||
00166       ((omx_base_component_Private->transientState == OMX_TransStateExecutingToIdle || 
00167         omx_base_component_Private->transientState == OMX_TransStatePauseToIdle) &&
00168       (PORT_IS_TUNNELED(openmaxStandPort) && !PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)))) {
00169     DEBUG(DEB_LEV_ERR, "In %s: Port %d is disabled comp = %s \n", __func__, (int)portIndex,omx_base_component_Private->name);
00170     return OMX_ErrorIncorrectStateOperation;
00171   }
00172 
00173   /* Temporarily disable this check for gst-openmax */
00174 #if NO_GST_OMX_PATCH
00175   {
00176   OMX_BOOL foundBuffer = OMX_FALSE;
00177   if(pBuffer!=NULL && pBuffer->pBuffer!=NULL) {
00178     for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){
00179     if (pBuffer->pBuffer == openmaxStandPort->pInternalBufferStorage[i]->pBuffer) {
00180       foundBuffer = OMX_TRUE;
00181       break;
00182     }
00183     }
00184   }
00185   if (!foundBuffer) {
00186     return OMX_ErrorBadParameter;
00187   }
00188   }
00189 #endif
00190 
00191   if ((err = checkHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE))) != OMX_ErrorNone) {
00192     DEBUG(DEB_LEV_ERR, "In %s: received wrong buffer header on input port\n", __func__);
00193     return err;
00194   }
00195   /*If port is not tunneled then simply return the buffer except paused state*/
00196   if (!PORT_IS_TUNNELED(openmaxStandPort) && (omx_base_component_Private->state != OMX_StatePause)) {
00197     openmaxStandPort->ReturnBufferFunction(openmaxStandPort,pBuffer);
00198     return OMX_ErrorNone;
00199   }
00200 
00201   /* And notify the buffer management thread we have a fresh new buffer to manage */
00202   if(!PORT_IS_BEING_FLUSHED(openmaxStandPort) && !(PORT_IS_BEING_DISABLED(openmaxStandPort) && PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort))){
00203       errQue = queue(openmaxStandPort->pBufferQueue, pBuffer);
00204       if (errQue) {
00205           /* /TODO the queue is full. This can be handled in a fine way with
00206            * some retrials, or other checking. For the moment this is a critical error
00207            * and simply causes the failure of this call
00208            */
00209           return OMX_ErrorInsufficientResources;
00210       }
00211       tsem_up(openmaxStandPort->pBufferSem);
00212       DEBUG(DEB_LEV_PARAMS, "In %s Signalling bMgmtSem Port Index=%d\n",__func__, (int)portIndex);
00213       tsem_up(omx_base_component_Private->bMgmtSem);
00214   } else if(PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)){
00215       DEBUG(DEB_LEV_FULL_SEQ, "In %s: Comp %s received io:%d buffer\n",
00216               __func__,omx_base_component_Private->name,(int)openmaxStandPort->sPortParam.nPortIndex);
00217       errQue = queue(openmaxStandPort->pBufferQueue, pBuffer);
00218       if (errQue) {
00219           /* /TODO the queue is full. This can be handled in a fine way with
00220            * some retrials, or other checking. For the moment this is a critical error
00221            * and simply causes the failure of this call
00222            */
00223           return OMX_ErrorInsufficientResources;
00224       }
00225       tsem_up(openmaxStandPort->pBufferSem);
00226   }
00227   else { // If port being flushed and not tunneled then return error
00228     DEBUG(DEB_LEV_ERR, "Port flushed but not tunneled in %s \n", __func__);
00229     return OMX_ErrorIncorrectStateOperation;
00230   }
00231   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s of component %p\n", __func__, omx_base_component_Private);
00232   return OMX_ErrorNone;
00233 }