Exemple #1
0
QUEUE_ERRORTYPE Queue::Get(fsl_osal_ptr pMsg)
{
    QNODE *pQNode = NULL;

    if(bBlocking == E_FSL_OSAL_TRUE)
        fsl_osal_sem_wait(usedNodesSem);
    else {
        if(fsl_osal_sem_trywait(usedNodesSem) != E_FSL_OSAL_SUCCESS)
            return QUEUE_NOT_READY;
    }

    fsl_osal_mutex_lock(lock);

    if(pHead == NULL) {
        fsl_osal_mutex_unlock(lock);
        return QUEUE_OVERFLOW;
    }

    pQNode = pHead;
    pHead = pHead->NextNode;
    fsl_osal_memcpy(pMsg, pQNode->pMsg, nMsgSize);
    pQNode->NextNode = pFreeNodes;
    pFreeNodes = pQNode;
    nQSize --;
    if(pHead == NULL)
        pTail = NULL;

    fsl_osal_sem_post(freeNodesSem);
    fsl_osal_mutex_unlock(lock);

    return QUEUE_SUCCESS;
}
Exemple #2
0
fsl_osal_u32 Queue::Size()
{
    fsl_osal_u32 ret = 0;

    fsl_osal_mutex_lock(lock);
    ret = nQSize;
    fsl_osal_mutex_unlock(lock);

    return ret;
}
OMX_ERRORTYPE Clock::SetStartTime(
        OMX_TIME_CONFIG_TIMESTAMPTYPE *pStartTime)
{
    OMX_ERRORTYPE ret = OMX_ErrorNone;
    OMX_TIME_MEDIATIMETYPE UpdateType;
    OMX_U32 nPortIndex;
    OMX_U32 i;

    if(CurState != OMX_TIME_ClockStateWaitingForStartTime)
        return OMX_ErrorIncorrectStateOperation;

    OMX_CHECK_STRUCT(pStartTime, OMX_TIME_CONFIG_TIMESTAMPTYPE, ret);
    if(ret != OMX_ErrorNone)
        return ret;

    nPortIndex = pStartTime->nPortIndex;
    if(nPortIndex >= nPorts) {
        LOG_ERROR("Bad port index[%d] when set start time to clock.\n", nPortIndex);
        return OMX_ErrorBadPortIndex;
    }

    fsl_osal_mutex_lock(lock);
    SegmentStartTime = MIN(SegmentStartTime, (OMX_U64)pStartTime->nTimestamp);
    LOG_DEBUG("%s,%d,set start time from port %d, ts %lld,SegmentStartTime %lld\n",__FUNCTION__,__LINE__,nPortIndex,pStartTime->nTimestamp,SegmentStartTime);
    StartTimeWaitMask &= ~(1 << nPortIndex);
    if(StartTimeWaitMask) {
        fsl_osal_mutex_unlock(lock);
        return OMX_ErrorNone;
    }

    /* start media clock now */
    CurState = OMX_TIME_ClockStateRunning;
    sState.eState = CurState;
    MediaTimeBase = SegmentStartTime;
    LOG_DEBUG("%s,%d,start new segment,set media time base to %lld\n",__FUNCTION__,__LINE__,MediaTimeBase);
    CurMediaAndWallTime(NULL, &WallTimeBase);

    OMX_INIT_STRUCT(&UpdateType, OMX_TIME_MEDIATIMETYPE);
    UpdateType.eUpdateType = OMX_TIME_UpdateClockStateChanged;
    UpdateType.eState = sState.eState;
    UpdateType.nMediaTimestamp = SegmentStartTime;
    SegmentStartTime = -1L;

    fsl_osal_mutex_unlock(lock);

    for(i=0; i<PORT_NUM; i++) {
        if(ports[i]->IsEnabled() == OMX_TRUE)
            MediaTimeUpdate(&UpdateType, i);
    }

    return OMX_ErrorNone;
}
Exemple #4
0
QUEUE_ERRORTYPE Queue::Get(fsl_osal_ptr pMsg, fsl_osal_u32 nIndex)
{
    QNODE *pQNode, *pQNodePrev = NULL;
    fsl_osal_u32 i;

    if(nIndex > nQSize) {
        fsl_osal_memset(pMsg, 0, nMsgSize);
        return QUEUE_FAILURE;
    }

    if(nIndex == 1)
        return Get(pMsg);

    if(bBlocking == E_FSL_OSAL_TRUE)
        fsl_osal_sem_wait(usedNodesSem);
    else {
        if(fsl_osal_sem_trywait(usedNodesSem) != E_FSL_OSAL_SUCCESS)
            return QUEUE_NOT_READY;
    }

    fsl_osal_mutex_lock(lock);

    if(pHead == NULL) {
        fsl_osal_mutex_unlock(lock);
        return QUEUE_OVERFLOW;
    }

    pQNodePrev = pHead;
    pQNode = pQNodePrev->NextNode;

    for(i=2; i<nIndex; i++){
        pQNodePrev = pQNodePrev->NextNode;
        pQNode = pQNode->NextNode;
    }

    fsl_osal_memcpy(pMsg, pQNode->pMsg, nMsgSize);

    pQNodePrev->NextNode = pQNode->NextNode;
    pQNode->NextNode = pFreeNodes;
    pFreeNodes = pQNode;
    nQSize --;

    if(pTail == pQNode)
        pTail = pQNodePrev;

    fsl_osal_sem_post(freeNodesSem);
    fsl_osal_mutex_unlock(lock);

    return QUEUE_SUCCESS;
}
OMX_ERRORTYPE Clock::SetRefTime(
        OMX_TIME_CONFIG_TIMESTAMPTYPE *pTs, 
        OMX_TIME_REFCLOCKTYPE eClock)
{
    if(eClock != RefClock)
        return OMX_ErrorNone;

    fsl_osal_mutex_lock(lock);
    CurMediaAndWallTime(NULL, &WallTimeBase);
    if(pTs->nTimestamp >= 0)
        MediaTimeBase = pTs->nTimestamp;
    fsl_osal_mutex_unlock(lock);
    LOG_DEBUG("%s,%d,Set reference time with ts %lld,from ref clock  %d, result wall time base %lld\n",__FUNCTION__,__LINE__,MediaTimeBase, RefClock,WallTimeBase);
    return OMX_ErrorNone;
}
OMX_ERRORTYPE IpulibRender::ResetDevice()
{
	fsl_osal_mutex_lock(lock);


	CloseDevice();

	OMX_STATETYPE eState = OMX_StateInvalid;
	GetState(&eState);
	if(eState == OMX_StatePause && bSuspend != OMX_TRUE)
		StartDeviceInPause();

	fsl_osal_mutex_unlock(lock);

	return OMX_ErrorNone;
}
Exemple #7
0
OMX_PTR PlatformResourceMgr::GetHwBuffer(
        OMX_PTR pVirtualAddr)
{
    PLATFORM_DATA *pData = NULL;
    OMX_PTR ptr = NULL;

    fsl_osal_mutex_lock(lock);
    pData = (PLATFORM_DATA*) SearchData(pVirtualAddr);
    if(pData == NULL) {
        fsl_osal_mutex_unlock(lock);
        return NULL;
    }
    ptr = pData->pPhyiscAddr;
    fsl_osal_mutex_unlock(lock);

    return ptr;
}
Exemple #8
0
OMX_ERRORTYPE PlatformResourceMgr::RemoveHwBuffer(
        OMX_PTR pVirtualAddr)
{
    PLATFORM_DATA *pData = NULL;

    fsl_osal_mutex_lock(lock);
    pData = (PLATFORM_DATA*) SearchData(pVirtualAddr);
    if(pData == NULL) {
        fsl_osal_mutex_unlock(lock);
        return OMX_ErrorUndefined;
    }
    PlatformDataList->Remove(pData);
    FSL_FREE(pData);
    fsl_osal_mutex_unlock(lock);

    return OMX_ErrorNone;
}
OMX_ERRORTYPE V4lRender::SetDeviceDisplayRegion()
{
	OMX_ERRORTYPE ret = OMX_ErrorNone;

	if(device <= 0)
		return OMX_ErrorNotReady;

	fsl_osal_mutex_lock(lock);
	V4lStreamOff(OMX_FALSE);
	ret = V4lSetOutputCrop();
	if(ret != OMX_ErrorNone)
	{
		fsl_osal_mutex_unlock(lock);
		return ret;
	}
	fsl_osal_mutex_unlock(lock);

	return ret;
}
OMX_ERRORTYPE Clock::SetTimeScale(
        OMX_TIME_CONFIG_SCALETYPE *pScale)
{
    OMX_ERRORTYPE ret = OMX_ErrorNone;
    OMX_TIME_MEDIATIMETYPE UpdateType;
    OMX_U32 i;

    OMX_CHECK_STRUCT(pScale, OMX_TIME_CONFIG_SCALETYPE, ret);
    if(ret != OMX_ErrorNone)
        return ret;

    if(pScale->xScale == Scale) {
        LOG_INFO("Set same scale value:[%d:%d]\n", pScale->xScale, Scale);
        return OMX_ErrorNone;
    }

    fsl_osal_mutex_lock(lock);

    CurMediaAndWallTime(&MediaTimeBase, NULL);
    CurMediaAndWallTime(NULL, &WallTimeBase);

    Scale = pScale->xScale;

    OMX_INIT_STRUCT(&UpdateType, OMX_TIME_MEDIATIMETYPE);
    UpdateType.eUpdateType = OMX_TIME_UpdateScaleChanged;
    UpdateType.xScale = Scale;

    fsl_osal_mutex_unlock(lock);

    for(i=0; i<PORT_NUM; i++) {
        if(ports[i]->IsEnabled() == OMX_TRUE)
            MediaTimeUpdate(&UpdateType, i);
    }

    fsl_osal_cond_broadcast(Cond);


    return ret;
}
Exemple #11
0
OMX_ERRORTYPE PlatformResourceMgr::AddHwBuffer(
        OMX_PTR pPhyiscAddr,
        OMX_PTR pVirtualAddr)
{
    PLATFORM_DATA *pData = NULL;

    pData = (PLATFORM_DATA*)FSL_MALLOC(sizeof(PLATFORM_DATA));
    if(pData == NULL)
        return OMX_ErrorInsufficientResources;

    pData->pVirtualAddr = pVirtualAddr;
    pData->pPhyiscAddr = pPhyiscAddr;

    fsl_osal_mutex_lock(lock);
    if(LIST_SUCCESS != PlatformDataList->Add(pData)) {
        FSL_FREE(pData);
        fsl_osal_mutex_unlock(lock);
        return OMX_ErrorUndefined;
    }
    fsl_osal_mutex_unlock(lock);

    return OMX_ErrorNone;
}
OMX_ERRORTYPE Clock::SetRefClock(
        OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE *pRefClock)
{
    OMX_ERRORTYPE ret = OMX_ErrorNone;

    OMX_CHECK_STRUCT(pRefClock, OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE, ret);
    if(ret != OMX_ErrorNone)
        return ret;

        
    LOG_DEBUG("%s,%d,Set reference clock %d, curr ref clock %d\n",__FUNCTION__,__LINE__, pRefClock->eClock, RefClock);
    if(RefClock == pRefClock->eClock) {
        LOG_INFO("Set same reference clock:[%d:%d]\n", pRefClock->eClock, RefClock);
        return OMX_ErrorNone;
    }

    fsl_osal_mutex_lock(lock);
    RefClock = pRefClock->eClock;
    fsl_osal_cond_broadcast(Cond);
    fsl_osal_mutex_unlock(lock);

    return OMX_ErrorNone;
}
OMX_ERRORTYPE IpulibRender::WriteDevice(
    OMX_BUFFERHEADERTYPE *pBufferHdr)
{
	OMX_ERRORTYPE ret = OMX_ErrorNone;

	fsl_osal_mutex_lock(lock);

	if(sCapture.eType == CAP_THUMBNAL)
	{
		fsl_osal_memcpy(sCapture.pBuffer, pBufferHdr->pBuffer, pBufferHdr->nFilledLen);
		sCapture.nFilledLen = pBufferHdr->nFilledLen;
		bCaptureFrameDone = OMX_TRUE;
		ports[0]->SendBuffer(pBufferHdr);
		fsl_osal_mutex_unlock(lock);
		return OMX_ErrorNone;
	}

	if(pBufferHdr->nFilledLen == 0)
	{
		ports[0]->SendBuffer(pBufferHdr);
		fsl_osal_mutex_unlock(lock);
		return OMX_ErrorNone;
	}

	pShowFrame = pBufferHdr->pBuffer;
	nFrameLen = pBufferHdr->nFilledLen;

	if(bSuspend == OMX_TRUE)
	{
		ports[0]->SendBuffer(pBufferHdr);
		fsl_osal_mutex_unlock(lock);
		return OMX_ErrorNone;
	}

	OMX_PTR pFrame = NULL;
	GetHwBuffer(pBufferHdr->pBuffer, &pFrame);

	if(bInitDev != OMX_TRUE)
	{
		ret = Init();
		if(ret != OMX_ErrorNone)
		{
			ports[0]->SendBuffer(pBufferHdr);
			fsl_osal_mutex_unlock(lock);
			return ret;
		}
		bInitDev = OMX_TRUE;
	}

	ret = RenderFrame(pFrame);
	if(ret != OMX_ErrorNone)
	{
		ports[0]->SendBuffer(pBufferHdr);
		fsl_osal_mutex_unlock(lock);
		return ret;
	}

	ports[0]->SendBuffer(pBufferHdr);

	fsl_osal_mutex_unlock(lock);

	return OMX_ErrorNone;
}
OMX_ERRORTYPE V4lRender::SetOutputMode()
{
	OMX_ERRORTYPE ret = OMX_ErrorNone;
	OMX_S32 output;
	OMX_STATETYPE eState = OMX_StateInvalid;

	if(device <= 0)
		return OMX_ErrorNotReady;
	if (bInTransitState == OMX_TRUE)
		return OMX_ErrorNotReady;

	fsl_osal_mutex_lock(lock);
	bInTransitState == OMX_TRUE;

	GetState(&eState);
	if(eState == OMX_StatePause)
		V4lStreamOff(OMX_TRUE);
	else
		V4lStreamOff(OMX_FALSE);


	output = 3;
	if(sOutputMode.bTv == OMX_TRUE)
	{
		if(sOutputMode.eFbLayer == LAYER1)
			output = 5;
		if(sOutputMode.eFbLayer == LAYER2)
			switch_to_tv(sOutputMode.eTvMode);
	}
	else
	{
		if(sOutputMode.eFbLayer == LAYER2)
			switch_to_lcd();
	}

	fsl_osal_memcpy(&sRectOut, &sOutputMode.sRectOut, sizeof(OMX_CONFIG_RECTTYPE));
	fsl_osal_memcpy(&sRectIn, &sOutputMode.sRectIn, sizeof(OMX_CONFIG_RECTTYPE));

	ret = V4lSetOutputLayer(output);
	if(ret != OMX_ErrorNone)
		goto err;

	ret = V4lSetInputCrop();
	if(ret != OMX_ErrorNone)
		goto err;

	ret = V4lSetOutputCrop();
	if(ret != OMX_ErrorNone)
		goto err;

	eRotation = sOutputMode.eRotation;
	ret = V4lSetRotation();
	if(ret != OMX_ErrorNone)
		goto err;


	if(eState == OMX_StatePause)
		V4lStreamOnInPause();

	fsl_osal_mutex_unlock(lock);
	return OMX_ErrorNone;

err:
	fsl_osal_mutex_unlock(lock);
	return ret;
}
OMX_ERRORTYPE IpulibRender::RenderSetConfig(
    OMX_INDEXTYPE nParamIndex,
    OMX_PTR pStructure)
{
	OMX_ERRORTYPE ret = OMX_ErrorNone;

	switch (nParamIndex)
	{
	case OMX_IndexOutputMode:
	{
		OMX_CONFIG_OUTPUTMODE *pOutputMode;
		pOutputMode = (OMX_CONFIG_OUTPUTMODE*)pStructure;
		CHECK_STRUCT(pOutputMode, OMX_CONFIG_OUTPUTMODE, ret);
		fsl_osal_memcpy(&sOutputMode, pOutputMode, sizeof(OMX_CONFIG_OUTPUTMODE));
		fsl_osal_memcpy(&sRectIn, &pOutputMode->sRectIn, sizeof(OMX_CONFIG_RECTTYPE));
		fsl_osal_memcpy(&sRectOut, &pOutputMode->sRectOut, sizeof(OMX_CONFIG_RECTTYPE));
		eRotation = pOutputMode->eRotation;
		ResetDevice();
	}
	break;
	case OMX_IndexConfigCaptureFrame:
	{
		OMX_CONFIG_CAPTUREFRAME *pCapture;
		pCapture = (OMX_CONFIG_CAPTUREFRAME*)pStructure;
		CHECK_STRUCT(pCapture, OMX_CONFIG_CAPTUREFRAME, ret);
		sCapture.eType = pCapture->eType;
		sCapture.pBuffer = pCapture->pBuffer;
		bCaptureFrameDone = OMX_FALSE;
		if (sCapture.eType == CAP_SNAPSHOT)
		{
			if(pShowFrame == NULL)
			{
				ret = OMX_ErrorUndefined;
				break;
			}
			fsl_osal_memcpy(sCapture.pBuffer, pShowFrame, nFrameLen);
			sCapture.nFilledLen = nFrameLen;
			bCaptureFrameDone = OMX_TRUE;
		}
	}
	break;
	case OMX_IndexSysSleep:
		OMX_CONFIG_SYSSLEEP *pSysSleep;
		pSysSleep = (OMX_CONFIG_SYSSLEEP *)pStructure;
		bSuspend = pSysSleep->bSleep;
		fsl_osal_mutex_lock(lock);
		if(OMX_TRUE == bSuspend)
		{
			CloseDevice();
		}
		else
		{
			OMX_STATETYPE eState = OMX_StateInvalid;
			GetState(&eState);
			if(eState == OMX_StatePause)
				StartDeviceInPause();
		}
		fsl_osal_mutex_unlock(lock);
		break;
	default:
		ret = OMX_ErrorUnsupportedIndex;
		break;
	}

	return ret;
}
OMX_ERRORTYPE V4lRender::WriteDevice(
    OMX_BUFFERHEADERTYPE *pBufferHdr)
{
	OMX_ERRORTYPE ret = OMX_ErrorNone;
	FB_DATA *fb;
	OMX_U32 nIndex;

	fsl_osal_mutex_lock(lock);

	LOG_DEBUG("WriteDevice: %p, nAllocating %d, FilledLen %d, nRenderFrames %d, nFrameBuffer %d, hMarkTargetComponent %p\n",
	          pBufferHdr, nAllocating, pBufferHdr->nFilledLen, nRenderFrames, nFrameBuffer, pBufferHdr->hMarkTargetComponent);


	if(nAllocating > 0)
	{
		V4lSearchBuffer(pBufferHdr->pBuffer, &nIndex);
		BufferHdrs[nIndex] = pBufferHdr;
		//LOG_DEBUG("nIndex %d, nQueuedBuffer %d\n", nIndex, nQueuedBuffer);
	}
	else
	{
		nIndex = (nRenderFrames % (nFrameBuffer-V4L_DUMMY_BUF_NUM));
		fb = &fb_data[nIndex];
		fsl_osal_memcpy(fb->pVirtualAddr, pBufferHdr->pBuffer, pBufferHdr->nFilledLen);
		BufferHdrs[nIndex] = pBufferHdr;
	}

	if(sCapture.eType == CAP_THUMBNAL)
	{
		CaptureFrame(nIndex);
		bCaptureFrameDone = OMX_TRUE;
		ports[IN_PORT]->SendBuffer(BufferHdrs[nIndex]);
		BufferHdrs[nIndex] = NULL;
		fsl_osal_mutex_unlock(lock);
		return OMX_ErrorNone;
	}

	V4lQueueBuffer(nIndex);
#ifdef USING_DUMMY_WORKAROUND
	if((2==nQueuedBuffer)&&(bFlushState==OMX_TRUE))
	{
		OMX_U32 nTmp;
		//make sure: always one valid buffer(except dummy buffer) will be dequeue later
		//otherwise: pause+seek will be very slow or timeout
		ASSERT(OMX_TRUE==bDummyValid);
		V4lDeQueueBuffer(&nTmp);
		ASSERT(nTmp==(nFrameBuffer-V4L_DUMMY_BUF_NUM));
		memcpy(fb_data[nFrameBuffer-V4L_DUMMY_BUF_NUM].pVirtualAddr,fb_data[nIndex].pVirtualAddr,fb_data[nIndex].nLength);
		V4lQueueBuffer(nFrameBuffer-V4L_DUMMY_BUF_NUM);
		bFlushState=OMX_FALSE;
	}
#else
	if(pBufferHdr->hMarkTargetComponent != NULL)
	{
		LOG_DEBUG("requeue current buffer to steam on v4l\n");
		if(bV4lNewApi)
		{
			//will bring unrecoverable error if the same buffer is queue twice
			//no display : pause -> seek -> no display -> resume -> display
			V4lQueueBuffer((nIndex+1)%nFrameBuffer); //enable another buffer if you want to have display when pause+seek
		}
		else
		{
			V4lQueueBuffer(nIndex);
		}
		//nQueuedBuffer--;
		//nRenderFrames--;
	}
#endif

	nIndex = 0;
	ret = V4lDeQueueBuffer(&nIndex);
	if(ret == OMX_ErrorNone)
	{
		OMX_BUFFERHEADERTYPE *pHdr = NULL;
		pHdr = BufferHdrs[nIndex];
		BufferHdrs[nIndex] = NULL;

		ports[IN_PORT]->SendBuffer(pHdr);
		//LOG_DEBUG("dequeued nIndex %d\n", nIndex);
	}
#ifndef USING_DUMMY_WORKAROUND
	// when seeking in pause state, previous frame has been flushed in FlushComponent(), here no chance to call SendBuffer() and
	// OMX_EventMark will not be sent , and then seek action fails. So we add this SendEventMark() to trigger OMX_EventMark.
	if(pBufferHdr->hMarkTargetComponent != NULL)
	{
		LOG_DEBUG("Send eventMark in pause state\n");
		ports[0]->SendEventMark(pBufferHdr);
	}
#endif
	fsl_osal_mutex_unlock(lock);

	return OMX_ErrorNone;
}
OMX_ERRORTYPE Clock::SetState(
        OMX_TIME_CONFIG_CLOCKSTATETYPE *pState)
{
    OMX_ERRORTYPE ret = OMX_ErrorNone;
    OMX_TIME_CLOCKSTATE NewState;
    OMX_TIME_MEDIATIMETYPE UpdateType;
    OMX_U32 i;

    OMX_CHECK_STRUCT(pState, OMX_TIME_CONFIG_CLOCKSTATETYPE, ret);
    if(ret != OMX_ErrorNone)
        return ret;

    NewState = pState->eState;
    if(NewState == CurState) {
        LOG_INFO("Set same state to clock: [%d:%d]\n", pState->eState, CurState);
        return OMX_ErrorNone;
    }

    fsl_osal_mutex_lock(lock);

    switch (NewState)
    {
        case OMX_TIME_ClockStateRunning:
            if(CurState == OMX_TIME_ClockStateWaitingForStartTime) {
                LOG_ERROR("Clock can't switch from WaitForStartTime to Running directly.\n");
                ret = OMX_ErrorIncorrectStateTransition;
                goto err;
            }
            /* Stop -> Running */
            fsl_osal_memcpy(&sState, pState, sizeof(OMX_TIME_CONFIG_CLOCKSTATETYPE));
            SegmentStartTime = sState.nStartTime;
            break;
        case OMX_TIME_ClockStateWaitingForStartTime:
            if(CurState == OMX_TIME_ClockStateRunning) {
                LOG_ERROR("Clock can't switch from Running to WaitForStartTime.\n");
                ret = OMX_ErrorIncorrectStateTransition;
                goto err;
            }
            /* Stop -> WaitForStartTime */
            fsl_osal_memcpy(&sState, pState, sizeof(OMX_TIME_CONFIG_CLOCKSTATETYPE));
            StartTimeWaitMask = sState.nWaitMask;
            break;
        case OMX_TIME_ClockStateStopped:
            /* Running->Stop / WaitForStartTime->Stop */
            sState.eState = OMX_TIME_ClockStateStopped;
            break;
        default :
            LOG_ERROR("Invalid clock state setting: %d\n", pState->eState);
            ret = OMX_ErrorIncorrectStateTransition;
            goto err;
    }

    CurState = sState.eState;
    OMX_INIT_STRUCT(&UpdateType, OMX_TIME_MEDIATIMETYPE);
    UpdateType.eUpdateType = OMX_TIME_UpdateClockStateChanged;
    UpdateType.eState = sState.eState;

    fsl_osal_mutex_unlock(lock);

    for(i=0; i<PORT_NUM; i++) {
        if(ports[i]->IsEnabled() == OMX_TRUE)
            MediaTimeUpdate(&UpdateType, i);
    }

    if(sState.eState == OMX_TIME_ClockStateStopped)
        fsl_osal_cond_broadcast(Cond);

    return ret;

err:
    fsl_osal_mutex_unlock(lock);
    return ret;
}