static void ft_fixup_port(void *blob, struct fm_eth_info *info, char *prop) { int off; uint32_t ph; phys_addr_t paddr = CONFIG_SYS_CCSRBAR_PHYS + info->compat_offset; u64 dtsec1_addr = (u64)CONFIG_SYS_CCSRBAR_PHYS + CONFIG_SYS_FSL_FM1_DTSEC1_OFFSET; off = fdt_node_offset_by_compat_reg(blob, prop, paddr); if (info->enabled) { fdt_fixup_phy_connection(blob, off, info->enet_if); board_ft_fman_fixup_port(blob, prop, paddr, info->port, off); return ; } #ifdef CONFIG_SYS_FMAN_V3 /* * Physically FM1_DTSEC9 and FM1_10GEC1 use the same dual-role MAC, when * FM1_10GEC1 is enabled and FM1_DTSEC9 is disabled, ensure that the * dual-role MAC is not disabled, ditto for other dual-role MACs. */ if (((info->port == FM1_DTSEC9) && (PORT_IS_ENABLED(FM1_10GEC1))) || ((info->port == FM1_DTSEC10) && (PORT_IS_ENABLED(FM1_10GEC2))) || ((info->port == FM1_10GEC1) && (PORT_IS_ENABLED(FM1_DTSEC9))) || ((info->port == FM1_10GEC2) && (PORT_IS_ENABLED(FM1_DTSEC10))) #if (CONFIG_SYS_NUM_FMAN == 2) || ((info->port == FM2_DTSEC9) && (PORT_IS_ENABLED(FM2_10GEC1))) || ((info->port == FM2_DTSEC10) && (PORT_IS_ENABLED(FM2_10GEC2))) || ((info->port == FM2_10GEC1) && (PORT_IS_ENABLED(FM2_DTSEC9))) || ((info->port == FM2_10GEC2) && (PORT_IS_ENABLED(FM2_DTSEC10))) #endif ) return; #endif /* board code might have caused offset to change */ off = fdt_node_offset_by_compat_reg(blob, prop, paddr); /* Don't disable FM1-DTSEC1 MAC as its used for MDIO */ if (paddr != dtsec1_addr) fdt_status_disabled(blob, off); /* disable the MAC node */ /* disable the fsl,dpa-ethernet node that points to the MAC */ ph = fdt_get_phandle(blob, off); do_fixup_by_prop(blob, "fsl,fman-mac", &ph, sizeof(ph), "status", "disabled", strlen("disabled") + 1, 1); }
void* omx_clocksrc_BufferMgmtFunction (void* param) { OMX_COMPONENTTYPE* openmaxStandComp = (OMX_COMPONENTTYPE*)param; omx_base_component_PrivateType* omx_base_component_Private=(omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate; omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private = (omx_clocksrc_component_PrivateType*)omx_base_component_Private; omx_base_clock_PortType *pOutPort[MAX_CLOCK_PORTS]; tsem_t* pOutputSem[MAX_CLOCK_PORTS]; queue_t* pOutputQueue[MAX_CLOCK_PORTS]; OMX_BUFFERHEADERTYPE* pOutputBuffer[MAX_CLOCK_PORTS]; OMX_BOOL isOutputBufferNeeded[MAX_CLOCK_PORTS],bPortsBeingFlushed = OMX_FALSE; int i,j,outBufExchanged[MAX_CLOCK_PORTS]; for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) { pOutPort[i] = (omx_base_clock_PortType *)omx_clocksrc_component_Private->ports[i]; pOutputSem[i] = pOutPort[i]->pBufferSem; pOutputQueue[i] = pOutPort[i]->pBufferQueue; pOutputBuffer[i] = NULL; isOutputBufferNeeded[i] = OMX_TRUE; outBufExchanged[i] = 0; } DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__); while(omx_clocksrc_component_Private->state == OMX_StateIdle || omx_clocksrc_component_Private->state == OMX_StateExecuting || omx_clocksrc_component_Private->state == OMX_StatePause || omx_clocksrc_component_Private->transientState == OMX_TransStateLoadedToIdle){ /*Wait till the ports are being flushed*/ pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex); for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) { bPortsBeingFlushed |= PORT_IS_BEING_FLUSHED(pOutPort[i]); } while(bPortsBeingFlushed) { pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex); for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) { if(isOutputBufferNeeded[i]==OMX_FALSE && PORT_IS_BEING_FLUSHED(pOutPort[i])) { pOutPort[i]->ReturnBufferFunction((omx_base_PortType*)pOutPort[i],pOutputBuffer[i]); outBufExchanged[i]--; pOutputBuffer[1]=NULL; isOutputBufferNeeded[i]=OMX_TRUE; DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning output buffer for port %i\n",i); } } tsem_up(omx_clocksrc_component_Private->flush_all_condition); tsem_down(omx_clocksrc_component_Private->flush_condition); pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex); bPortsBeingFlushed = OMX_FALSE; for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) { bPortsBeingFlushed |= PORT_IS_BEING_FLUSHED(pOutPort[i]); } } pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex); /*Wait for clock state event*/ DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Waiting for clock event\n",__func__); tsem_down(omx_clocksrc_component_Private->clockEventSem); DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s clock event occured semval=%d \n",__func__,omx_clocksrc_component_Private->clockEventSem->semval); /*If port is not tunneled then simply return the buffer except paused state*/ if(omx_clocksrc_component_Private->transientState == OMX_TransStatePauseToExecuting) { for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) { if(!PORT_IS_TUNNELED(pOutPort[i])) { if(pOutputSem[i]->semval>0 && isOutputBufferNeeded[i]==OMX_TRUE ) { tsem_down(pOutputSem[i]); if(pOutputQueue[i]->nelem>0){ outBufExchanged[i]++; isOutputBufferNeeded[i]=OMX_FALSE; pOutputBuffer[i] = dequeue(pOutputQueue[i]); if(pOutputBuffer[i] == NULL){ DEBUG(DEB_LEV_ERR, "Had NULL output buffer!!\n"); break; } } } if(isOutputBufferNeeded[i]==OMX_FALSE) { /*Output Buffer has been produced or EOS. So, return output buffer and get new buffer*/ if(pOutputBuffer[i]->nFilledLen!=0) { DEBUG(DEB_LEV_ERR, "In %s Returning Output nFilledLen=%d (line=%d)\n", __func__,(int)pOutputBuffer[i]->nFilledLen,__LINE__); pOutPort[i]->ReturnBufferFunction((omx_base_PortType*)pOutPort[i],pOutputBuffer[i]); outBufExchanged[i]--; pOutputBuffer[i]=NULL; isOutputBufferNeeded[i]=OMX_TRUE; } } } } omx_clocksrc_component_Private->transientState = OMX_TransStateMax; } if(omx_clocksrc_component_Private->state == OMX_StateLoaded || omx_clocksrc_component_Private->state == OMX_StateInvalid || omx_clocksrc_component_Private->transientState == OMX_TransStateIdleToLoaded || omx_clocksrc_component_Private->transientState == OMX_TransStateInvalid) { DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting (line %d)\n",__func__,__LINE__); break; } for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) { if(pOutPort[i]->sMediaTime.eUpdateType == OMX_TIME_UpdateClockStateChanged || pOutPort[i]->sMediaTime.eUpdateType == OMX_TIME_UpdateScaleChanged || pOutPort[i]->sMediaTime.eUpdateType == OMX_TIME_UpdateRequestFulfillment) { if((isOutputBufferNeeded[i]==OMX_TRUE && pOutputSem[i]->semval==0) && (omx_clocksrc_component_Private->state != OMX_StateLoaded && omx_clocksrc_component_Private->state != OMX_StateInvalid) && PORT_IS_ENABLED(pOutPort[i])) { //Signalled from EmptyThisBuffer or FillThisBuffer or some where else DEBUG(DEB_LEV_FULL_SEQ, "Waiting for next output buffer %i\n",i); tsem_down(omx_clocksrc_component_Private->bMgmtSem); } if(omx_clocksrc_component_Private->state == OMX_StateLoaded || omx_clocksrc_component_Private->state == OMX_StateInvalid || omx_clocksrc_component_Private->transientState == OMX_TransStateIdleToLoaded || omx_clocksrc_component_Private->transientState == OMX_TransStateInvalid) { DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting (line %d)\n",__func__,__LINE__); break; } if(pOutputSem[i]->semval>0 && isOutputBufferNeeded[i]==OMX_TRUE ) { tsem_down(pOutputSem[i]); if(pOutputQueue[i]->nelem>0){ outBufExchanged[i]++; isOutputBufferNeeded[i]=OMX_FALSE; pOutputBuffer[i] = dequeue(pOutputQueue[i]); if(pOutputBuffer[i] == NULL){ DEBUG(DEB_LEV_ERR, "Had NULL output buffer!!\n"); break; } } } else { DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Output buffer not available Port %d (line=%d)\n",__func__,(int)i,__LINE__); /*Check if any dummy bMgmtSem signal and ports are flushing*/ pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex); bPortsBeingFlushed = OMX_FALSE; for(j=0;j<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;j++) { bPortsBeingFlushed |= PORT_IS_BEING_FLUSHED(pOutPort[j]); } pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex); if(bPortsBeingFlushed) { DEBUG(DEB_LEV_ERR, "In %s Ports are being flushed - breaking (line %d)\n",__func__,__LINE__); break; } } /*Process Output buffer of Port i */ if(isOutputBufferNeeded[i]==OMX_FALSE) { if (omx_clocksrc_component_Private->BufferMgmtCallback) { (*(omx_clocksrc_component_Private->BufferMgmtCallback))(openmaxStandComp, pOutputBuffer[i]); } else { /*If no buffer management call back then don't produce any output buffer*/ pOutputBuffer[i]->nFilledLen = 0; } /*Output Buffer has been produced or EOS. So, return output buffer and get new buffer*/ if(pOutputBuffer[i]->nFilledLen!=0) { pOutPort[i]->ReturnBufferFunction((omx_base_PortType*)pOutPort[i],pOutputBuffer[i]); outBufExchanged[i]--; pOutputBuffer[i]=NULL; isOutputBufferNeeded[i]=OMX_TRUE; } } } } DEBUG(DEB_LEV_SIMPLE_SEQ, "Sent Clock Event for all ports\n"); tsem_up(omx_clocksrc_component_Private->clockEventCompleteSem); } DEBUG(DEB_LEV_SIMPLE_SEQ,"Exiting Buffer Management Thread\n"); return NULL; }
OMX_ERRORTYPE omx_clocksrc_component_SetConfig( OMX_HANDLETYPE hComponent, OMX_INDEXTYPE nIndex, OMX_PTR pComponentConfigStructure) { OMX_COMPONENTTYPE* omxComponent = (OMX_COMPONENTTYPE*)hComponent; omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private = (omx_clocksrc_component_PrivateType*)omxComponent->pComponentPrivate; OMX_TIME_CONFIG_CLOCKSTATETYPE* clockstate; OMX_TIME_CONFIG_TIMESTAMPTYPE* sRefTimeStamp; OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE* pRefClock; OMX_U32 portIndex; omx_base_clock_PortType *pPort; OMX_TIME_CONFIG_SCALETYPE *pConfigScale; OMX_U32 nMask; OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE* sMediaTimeRequest; int i; struct timeval tv; struct timezone zv; OMX_TICKS walltime, mediatime, mediaTimediff, wallTimediff; OMX_S32 Scale; unsigned int sleeptime; DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__); switch (nIndex) { case OMX_IndexConfigTimeClockState : { clockstate = (OMX_TIME_CONFIG_CLOCKSTATETYPE*) pComponentConfigStructure; switch (clockstate->eState) { case OMX_TIME_ClockStateRunning: if(omx_clocksrc_component_Private->sClockState.eState == OMX_TIME_ClockStateRunning) { DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Received OMX_TIME_ClockStateRunning again\n",__func__); } DEBUG(DEB_LEV_SIMPLE_SEQ,"in %s ...set to OMX_TIME_ClockStateRunning\n",__func__); memcpy(&omx_clocksrc_component_Private->sClockState, clockstate, sizeof(OMX_TIME_CONFIG_CLOCKSTATETYPE)); omx_clocksrc_component_Private->eUpdateType = OMX_TIME_UpdateClockStateChanged; /* update the state change in all port */ for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) { pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[i]; pPort->sMediaTime.eUpdateType = OMX_TIME_UpdateClockStateChanged; pPort->sMediaTime.eState = OMX_TIME_ClockStateRunning; pPort->sMediaTime.xScale = omx_clocksrc_component_Private->sConfigScale.xScale; } /*Signal Buffer Management Thread*/ tsem_up(omx_clocksrc_component_Private->clockEventSem); DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for Clock Running Event for all ports\n"); tsem_down(omx_clocksrc_component_Private->clockEventCompleteSem); break; case OMX_TIME_ClockStateWaitingForStartTime: if(omx_clocksrc_component_Private->sClockState.eState == OMX_TIME_ClockStateRunning) { return OMX_ErrorIncorrectStateTransition; } else if(omx_clocksrc_component_Private->sClockState.eState == OMX_TIME_ClockStateWaitingForStartTime) { return OMX_ErrorSameState; } DEBUG(DEB_LEV_SIMPLE_SEQ," in %s ...set to OMX_TIME_ClockStateWaitingForStartTime mask sent=%d\n",__func__,(int)clockstate->nWaitMask); memcpy(&omx_clocksrc_component_Private->sClockState, clockstate, sizeof(OMX_TIME_CONFIG_CLOCKSTATETYPE)); break; case OMX_TIME_ClockStateStopped: DEBUG(DEB_LEV_SIMPLE_SEQ," in %s ...set to OMX_TIME_ClockStateStopped\n",__func__); memcpy(&omx_clocksrc_component_Private->sClockState, clockstate, sizeof(OMX_TIME_CONFIG_CLOCKSTATETYPE)); omx_clocksrc_component_Private->eUpdateType = OMX_TIME_UpdateClockStateChanged; /* update the state change in all port */ for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) { pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[i]; pPort->sMediaTime.eUpdateType = OMX_TIME_UpdateClockStateChanged; pPort->sMediaTime.eState = OMX_TIME_ClockStateStopped; pPort->sMediaTime.xScale = omx_clocksrc_component_Private->sConfigScale.xScale; } /*Signal Buffer Management Thread*/ tsem_up(omx_clocksrc_component_Private->clockEventSem); DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for Clock Stop Event for all ports\n"); tsem_down(omx_clocksrc_component_Private->clockEventCompleteSem); break; default: break; } } break; case OMX_IndexConfigTimeClientStartTime: sRefTimeStamp = (OMX_TIME_CONFIG_TIMESTAMPTYPE*) pComponentConfigStructure; portIndex = sRefTimeStamp->nPortIndex; if(portIndex > omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts) { return OMX_ErrorBadPortIndex; } pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[portIndex]; if(!PORT_IS_ENABLED(pPort)) { DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Port is disabled \n",__func__); return OMX_ErrorBadParameter; } memcpy(&pPort->sTimeStamp, sRefTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE)); /* update the nWaitMask to clear the flag for the client which has sent its start time */ if(omx_clocksrc_component_Private->sClockState.nWaitMask) { DEBUG(DEB_LEV_SIMPLE_SEQ,"refTime set is =%x \n",(int)pPort->sTimeStamp.nTimestamp); nMask = ~(0x1 << portIndex); omx_clocksrc_component_Private->sClockState.nWaitMask = omx_clocksrc_component_Private->sClockState.nWaitMask & nMask; if(omx_clocksrc_component_Private->sMinStartTime.nTimestamp >= pPort->sTimeStamp.nTimestamp){ omx_clocksrc_component_Private->sMinStartTime.nTimestamp = pPort->sTimeStamp.nTimestamp; omx_clocksrc_component_Private->sMinStartTime.nPortIndex = pPort->sTimeStamp.nPortIndex; } } if(!omx_clocksrc_component_Private->sClockState.nWaitMask && omx_clocksrc_component_Private->sClockState.eState == OMX_TIME_ClockStateWaitingForStartTime) { omx_clocksrc_component_Private->sClockState.eState = OMX_TIME_ClockStateRunning; omx_clocksrc_component_Private->sClockState.nStartTime = omx_clocksrc_component_Private->sMinStartTime.nTimestamp; omx_clocksrc_component_Private->MediaTimeBase = omx_clocksrc_component_Private->sMinStartTime.nTimestamp; gettimeofday(&tv,&zv); walltime = ((OMX_TICKS)tv.tv_sec)*1000000 + ((OMX_TICKS)tv.tv_usec); omx_clocksrc_component_Private->WallTimeBase = walltime; DEBUG(DEB_LEV_SIMPLE_SEQ,"Mediatimebase=%llx walltimebase=%llx \n",omx_clocksrc_component_Private->MediaTimeBase,omx_clocksrc_component_Private->WallTimeBase); omx_clocksrc_component_Private->eUpdateType = OMX_TIME_UpdateClockStateChanged; /* update the state change in all port */ for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) { pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[i]; pPort->sMediaTime.eUpdateType = OMX_TIME_UpdateClockStateChanged; pPort->sMediaTime.eState = OMX_TIME_ClockStateRunning; pPort->sMediaTime.xScale = omx_clocksrc_component_Private->sConfigScale.xScale; } /*Signal Buffer Management Thread*/ tsem_up(omx_clocksrc_component_Private->clockEventSem); DEBUG(DEB_LEV_SIMPLE_SEQ,"setting the state to running from %s \n",__func__); DEBUG(DEB_LEV_SIMPLE_SEQ,"Waiting for Clock Running Event for all ports in case OMX_IndexConfigTimeClientStartTime\n"); tsem_down(omx_clocksrc_component_Private->clockEventCompleteSem); } break; case OMX_IndexConfigTimeActiveRefClock : pRefClock = (OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE*) pComponentConfigStructure; memcpy(&omx_clocksrc_component_Private->sRefClock, pRefClock, sizeof(OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE)); break; case OMX_IndexConfigTimeCurrentAudioReference: sRefTimeStamp = (OMX_TIME_CONFIG_TIMESTAMPTYPE*) pComponentConfigStructure; portIndex = sRefTimeStamp->nPortIndex; if(portIndex > omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts) { return OMX_ErrorBadPortIndex; } pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[portIndex]; memcpy(&pPort->sTimeStamp, sRefTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE)); gettimeofday(&tv,&zv); walltime = ((OMX_TICKS)tv.tv_sec)*1000000 + ((OMX_TICKS)tv.tv_usec); omx_clocksrc_component_Private->WallTimeBase = walltime; omx_clocksrc_component_Private->MediaTimeBase = sRefTimeStamp->nTimestamp; /* set the mediatime base of the received time stamp*/ break; case OMX_IndexConfigTimeCurrentVideoReference: sRefTimeStamp = (OMX_TIME_CONFIG_TIMESTAMPTYPE*) pComponentConfigStructure; portIndex = sRefTimeStamp->nPortIndex; if(portIndex > omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts) { return OMX_ErrorBadPortIndex; } pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[portIndex]; memcpy(&pPort->sTimeStamp, sRefTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE)); gettimeofday(&tv,&zv); walltime = ((OMX_TICKS)tv.tv_sec)*1000000 + ((OMX_TICKS)tv.tv_usec); omx_clocksrc_component_Private->WallTimeBase = walltime; omx_clocksrc_component_Private->MediaTimeBase = sRefTimeStamp->nTimestamp; /* set the mediatime base of the received time stamp*/ break; case OMX_IndexConfigTimeScale: /* update the mediatime base and walltime base using the current scale value*/ Scale = omx_clocksrc_component_Private->sConfigScale.xScale >> 16; //* the scale currently in use, right shifted as Q16 format is used for the scale gettimeofday(&tv,&zv); walltime = ((OMX_TICKS)tv.tv_sec)*1000000 + ((OMX_TICKS)tv.tv_usec); mediatime = omx_clocksrc_component_Private->MediaTimeBase + Scale*(walltime - omx_clocksrc_component_Private->WallTimeBase); omx_clocksrc_component_Private->WallTimeBase = walltime; // suitable start time to be used here omx_clocksrc_component_Private->MediaTimeBase = mediatime; // TODO - needs to be checked /* update the new scale value */ pConfigScale = (OMX_TIME_CONFIG_SCALETYPE*) pComponentConfigStructure; memcpy( &omx_clocksrc_component_Private->sConfigScale,pConfigScale, sizeof(OMX_TIME_CONFIG_SCALETYPE)); omx_clocksrc_component_Private->eUpdateType = OMX_TIME_UpdateScaleChanged; /* update the scale change in all ports */ for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) { pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[i]; pPort->sMediaTime.eUpdateType = OMX_TIME_UpdateScaleChanged; pPort->sMediaTime.eState = OMX_TIME_ClockStateRunning; pPort->sMediaTime.xScale = omx_clocksrc_component_Private->sConfigScale.xScale; pPort->sMediaTime.nMediaTimestamp = omx_clocksrc_component_Private->MediaTimeBase; pPort->sMediaTime.nWallTimeAtMediaTime = omx_clocksrc_component_Private->WallTimeBase; } /*Signal Buffer Management Thread*/ tsem_up(omx_clocksrc_component_Private->clockEventSem); DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for Scale Change Event for all ports\n"); tsem_down(omx_clocksrc_component_Private->clockEventCompleteSem); break; case OMX_IndexConfigTimeMediaTimeRequest: Scale = omx_clocksrc_component_Private->sConfigScale.xScale >> 16; if(omx_clocksrc_component_Private->sClockState.eState != OMX_TIME_ClockStateStopped && Scale != 0) {//TODO- what happens if request comes in pause mode sMediaTimeRequest = (OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE*) pComponentConfigStructure; portIndex = sMediaTimeRequest->nPortIndex; pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[portIndex]; memcpy(&pPort->sMediaTimeRequest, sMediaTimeRequest, sizeof(OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE)); gettimeofday(&tv,&zv); walltime = ((OMX_TICKS)tv.tv_sec)*1000000 + ((OMX_TICKS)tv.tv_usec); mediatime = omx_clocksrc_component_Private->MediaTimeBase + Scale*(walltime - omx_clocksrc_component_Private->WallTimeBase); int thresh=2000; // TODO - what is a good threshold to use mediaTimediff = (sMediaTimeRequest->nMediaTimestamp - (sMediaTimeRequest->nOffset*Scale)) - mediatime; DEBUG(DEB_LEV_SIMPLE_SEQ," pI=%d MTD=%lld MT=%lld RT=%lld offset=%lld, Scale=%d\n", (int)portIndex,mediaTimediff,mediatime,sMediaTimeRequest->nMediaTimestamp,sMediaTimeRequest->nOffset,(int)Scale); if((mediaTimediff<0 && Scale>0) || (mediaTimediff>0 && Scale<0)) { /* if mediatime has already elapsed then request can not be fullfilled */ DEBUG(DEB_LEV_SIMPLE_SEQ," pI=%d RNF MTD<0 MB=%lld WB=%lld MT=%lld RT=%lld WT=%lld offset=%lld, Scale=%d\n", (int)portIndex,omx_clocksrc_component_Private->MediaTimeBase,omx_clocksrc_component_Private->WallTimeBase, mediatime,sMediaTimeRequest->nMediaTimestamp,walltime,sMediaTimeRequest->nOffset,(int)Scale); pPort->sMediaTime.eUpdateType = OMX_TIME_UpdateRequestFulfillment; // TODO : to be checked pPort->sMediaTime.nMediaTimestamp = sMediaTimeRequest->nMediaTimestamp; pPort->sMediaTime.nOffset = 0xFFFFFFFF; }else{ wallTimediff = mediaTimediff/Scale; if(mediaTimediff){ if(wallTimediff>thresh) { sleeptime = (unsigned int) (wallTimediff-thresh); usleep(sleeptime); wallTimediff = thresh; // ask : can I use this as the new walltimediff gettimeofday(&tv,&zv); walltime = ((OMX_TICKS)tv.tv_sec)*1000000 + ((OMX_TICKS)tv.tv_usec); mediatime = omx_clocksrc_component_Private->MediaTimeBase + Scale*(walltime - omx_clocksrc_component_Private->WallTimeBase); } //pPort->sMediaTime.nMediaTimestamp = mediatime; pPort->sMediaTime.nMediaTimestamp = sMediaTimeRequest->nMediaTimestamp; ///???? pPort->sMediaTime.nWallTimeAtMediaTime = walltime + wallTimediff; //?????? pPort->sMediaTime.nOffset = wallTimediff; //???? pPort->sMediaTime.xScale = Scale; pPort->sMediaTime.eUpdateType = OMX_TIME_UpdateRequestFulfillment; DEBUG(DEB_LEV_SIMPLE_SEQ,"pI=%d MB=%lld WB=%lld MT=%lld RT=%lld WT=%lld \n",(int)portIndex, omx_clocksrc_component_Private->MediaTimeBase,omx_clocksrc_component_Private->WallTimeBase, mediatime,sMediaTimeRequest->nMediaTimestamp,walltime); } } /*Signal Buffer Management Thread*/ tsem_up(omx_clocksrc_component_Private->clockEventSem); DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for Scale Change Event for all ports\n"); tsem_down(omx_clocksrc_component_Private->clockEventCompleteSem); } else { DEBUG(DEB_LEV_ERR,"In %s Clock State=%x Scale=%x Line=%d \n", __func__,(int)omx_clocksrc_component_Private->sClockState.eState,(int)Scale,__LINE__); } break; default: return OMX_ErrorBadParameter; break; } return OMX_ErrorNone; }
/** @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 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 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; }