⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smlelem.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    HX_ASSERT(pSyncAncestor);

    // make sure that we do not have an illegal begin value
    // if we have a seq for a parent.
    // /Note: we want to use our sync ancestor, not our parent, because
    // our parent could be a non-time-container like <a>, <switch>,
    // or <priorityClass>:
    if ((pSyncAncestor  &&  SMILSeq == pSyncAncestor->m_tag  &&
	// /OK if parent seq was created to expand for repeat purposes:
	!m_pNode->m_bRepeatHandled)  &&
	( (!SUCCEEDED(rettimeval)  ||  NULL==pNextResolvedTimeValue)  ||
	(pNextResolvedTimeValue->m_type != SmilTimeOffset && 
	pNextResolvedTimeValue->m_type != SmilTimeClockValue) ) )
    {
	// only offsets are legal values...
	ret = HXR_INVALID_PARAMETER;
	goto cleanup;
    }

    // /For excl descendants, we don't want to declare that a begin time
    // has been set, because we need to figure out whether or not to
    // schedule it based on when other excl children begin (which we may
    // not know yet):

    if (SUCCEEDED(rettimeval) && NULL != pNextResolvedTimeValue)
    {
	if (pListOfAllResolvedBeginTimes)
	{
	    // /Go through this list and insert each into the pending list:
	    LISTPOSITION lPosTmp =
		    pListOfAllResolvedBeginTimes->GetHeadPosition();
	    while (lPosTmp)
	    {
		SmilTimeValue* pTmpVal = (SmilTimeValue*)
			pListOfAllResolvedBeginTimes->GetAt(lPosTmp);
		if (pTmpVal  &&  pTmpVal->isTimeResolved()  &&
			pTmpVal->m_pElement)
		{
		    if (pTmpVal != pNextResolvedTimeValue  ||
			    bIsDescendantOfExcl)
		    {
			// /(?XXXEH- TODO: insert into list based on resolved
			// time?  note that begin="20s;0s" works OK, so...?)
			if (pParser->EstablishBeginTimeList())
			{
			    CHXSimpleList* pList =
				    pParser->GetPendingBeginTimeList();
			    // /Don't add if it's a duplicate:
			    if (!pParser->isDuplicateEntry(pList, pTmpVal))
			    {
				pList->AddTail(pTmpVal);
			    }
			}
		    }
		}
		else
		{
		    HX_ASSERT(0  &&  "timeval invalid");
		}
    		pListOfAllResolvedBeginTimes->GetNext(lPosTmp);
	    } // /end while(lPos...).
	}
	HX_DELETE(pListOfAllResolvedBeginTimes);
	
	if (!bIsDescendantOfExcl)
	{
	    bBeginTimeHasBeenSet = TRUE;
	    HX_ASSERT(pNextResolvedTimeValue->isTimeResolved());
	    switch (pNextResolvedTimeValue->m_type)
	    {
		case SmilTimeOffset:
		case SmilTimeClockValue:
		{
		    // /XXXEH- is this what we really want to do?
		    // Alternatively, we could have resolved-to "base" time
		    // as 0 and then m_lOffset is added to get resolved-to
		    // "offset" time:
		    m_lBeginOffset = pNextResolvedTimeValue->getTimeOffset();
		    m_bBeginOffsetSet = TRUE;
		    // /Handle this now for time containers who never get
		    // called with a TrackDurationSet():
		    m_bCurBeginIsOffsetFromSyncBase = TRUE;
		    m_ulBeginOffsetFromSyncBase = m_lBeginOffset;

#if defined(_DEBUG) // /XXXEH- testing!:
		    LONG32 lResolvedToTime = 0;
		    HX_RESULT tmprslt =
			    pNextResolvedTimeValue->getEffectiveResolvedTime(
			    lResolvedToTime);
		    HX_ASSERT(tmprslt==HXR_OK  &&
			    m_lBeginOffset == lResolvedToTime);
#endif
		}
		break;

		case SmilTimeEvent:
#if defined(ENABLE_SYNC_TO_PREV)
		case SmilTimeSyncToPrev:
#endif
		case SmilTimeSyncBase:
		{
		    // /NOTE: this's time must be *resolved* already which
		    // shouldn't happen yet:
		    HX_ASSERT(!pNextResolvedTimeValue->isTimeResolved());
		}
		break;

                case SmilTimeMediaMarker:
                {
		    HX_ASSERT(!pNextResolvedTimeValue->isTimeResolved());
                }
                break;

		case SmilTimeWallclock:
		{
		    // /XXXEH- wouldn't it be better to use
		    // getEffectiveResolvedTime() here(?) so as to treat all time
		    // types consistently?
		    m_lBeginOffset = pNextResolvedTimeValue->getTimeOffset();
		    m_bBeginOffsetSet = TRUE;
		    // /Handle this now for time containers who never get
		    // called with a TrackDurationSet():
		    m_bCurBeginIsOffsetFromSyncBase = TRUE;
		    m_ulBeginOffsetFromSyncBase = m_lBeginOffset;

		    m_bWallClockBegin = TRUE;
		}
		break;

		default:
		    HX_ASSERT(0);
		    break;
	    } // /end of "switch(pNextResolvedTimeValue->m_type)".
	} // /end of "if (!bIsDescendantOfExcl)".
    }

    // /Now, go through all unresolved begin times and add this element to
    // the appropriate list(s) for each unresolved time value found:
    if (m_pBeginTimeList)
    {
	lPos = m_pBeginTimeList->GetHeadPosition();
    }

    if (NULL == lPos) // /list is empty.
    {
	goto cleanup;
    }

    while (lPos  &&  HXR_OK == ret)
    {
	SmilTimeValue* pTmpVal = (SmilTimeValue*)m_pBeginTimeList->GetAt(lPos);

	if (pTmpVal  &&  !pTmpVal->isTimeResolved())
	{
	    switch (pTmpVal->m_type)
	    {
	    case SmilTimeOffset:
	    case SmilTimeClockValue:
		{
		    // /We shouldn't ever get here because clock times are
		    // always resolved:
		    HX_ASSERT(pTmpVal->isTimeResolved());
		}
		break;
	    case SmilTimeSyncBase:
		{
		    pParser->addBeginTimeSyncElement(this);
		    if (!bBeginTimeHasBeenSet)
		    {
			m_BeginEventSourceID = pTmpVal->m_idRef;
			m_nBeginEventSourceTag = pTmpVal->m_position;
			// /NOTE: this is unresolved:
			m_lBeginEventClockValue =
				pTmpVal->getTimeOffset();
		    }
		    // /Fixes BUG-20010521_syncArcToElementWith...smil
		    // where begin="0s;x.end" and x.end was being ignored:
		    else
		    {
			if (!m_BeginEventSourceID.GetLength())
			{
			    m_BeginEventSourceID = pTmpVal->m_idRef;
			    m_nBeginEventSourceTag = pTmpVal->m_position;
			    // /NOTE: this is unresolved:
			    m_lBeginEventClockValue = pTmpVal->getTimeOffset();
			}
			else
			{
			    HX_ASSERT(0  &&
				"XXXEHodge: need to handle multiple sync-arc begins");
			    // /XXXEH- TODO: if m_BeginEventSourceID is already
			    // set due to another sync-arc begin time, we need
			    // to have a list of m_BeginEventSourceID's & ...etc.
			    // Currently, just the first one wins.  We could
			    // treat this sync-arc as a beginEvent event-arc...
			    // (We also need to handle this in SetEndTime().)
			}

		    }
		}
		break;
#if defined(ENABLE_SYNC_TO_PREV)
	    case SmilTimeSyncToPrev:
		{
		    // /XXXEH- shouldn't we treat this just like we treat the
		    // sync base case above by doing the following?:
		    //	    pParser->addBeginTimeSyncElement(this);
		    // /XXXEH- make sure we handle begin="3s; prev.end" where
		    // both are valid times; the following doesn't handle this
		    // case:
		    if (!bBeginTimeHasBeenSet)
		    {
			SMILNode* pSibling =
				m_pNode->m_pParent->getFirstChild();
			// /Spec says to use parent time container's begin if
			// m_pNode is the first child (and has no prev
			// sibling):
			SMILNode* pLastNode = m_pNode->m_pParent;
			while (pSibling)
			{
			    if (pSibling->m_id == m_pNode->m_id)
			    {
				// we found our boy...
				break;
			    }
			    pLastNode = pSibling;
			    // /XXXEH- TODO: skip over children that aren't
			    // *timed* elements, e.g., <a> tags; maybe we
			    // are supposed to use a non-timed-prev-element's
			    // last timed child, if any, and, if none exists,
			    // use it's prev timed sibling???:
			    pSibling = m_pNode->m_pParent->getNextChild();
			}
			HX_ASSERT(pSibling && pLastNode);
			if (pSibling && pLastNode)
			{
			    // /First, if we had no prev sibling, then
			    // we need to use our parent time container's
			    // begin time as our sync base:
			    if (pLastNode == m_pNode->m_pParent)
			    {
				SMILNode* pFirstTimeContainerAncestor =
					pParser->getSyncAncestor(m_pNode);
				// /There should ALWAYS be a time container
				// ancestor, even if it's the implied seq
				// that we create when no time container
				// exists as the 1st timed child of the body:
				HX_ASSERT(pFirstTimeContainerAncestor);
				if (pFirstTimeContainerAncestor)
				{
#if XXXEH_
/* /Need to figure out if this is earlier than any current times and, if
so, call insertElementWithPendingBeginOrEnd() with the earlier time, else
call insertElementWithPendingBeginOrEnd() with this (pTmpVal) time:
*/
#endif
				    // /For parent as prev, we can just treat
				    // this as a SmilTimeOffset value since
				    // they're essentially the same thing:
				    pLastNode = pFirstTimeContainerAncestor;
				    m_lBeginOffset= pTmpVal->getTimeOffset();
				    pTmpVal->m_type = SmilTimeOffset;
				    pTmpVal->setIsTimeResolved(TRUE);
				    m_bBeginOffsetSet = TRUE;
				}
				// /else give up; can't do anything here.
			    }
			    else // /Use prev sibling time:
			    {
				m_BeginEventSourceID = pLastNode->m_id;
				// /XXXEH- wouldn't it be better to use
				// getEffectiveResolvedTime() here(?) so as
				// to treat all time types consistently?
				m_lBeginEventClockValue =
					pTmpVal->getTimeOffset();
				m_nBeginEventSourceTag =
					pTmpVal->m_position;
			    }
			}
			else
			{
			    ret = HXR_FAIL;
			}
		    }
		}
		break;
#endif
	    case SmilTimeEvent:
		{
		    pParser->addBeginEventElement(pTmpVal);
		}
                break;
            case SmilTimeMediaMarker:
                {
                    pParser->addBeginMediaMarkerSyncElement(pTmpVal);
                }
                break;
            case SmilTimeWallclock:
		{
		    // /We shouldn't ever get here because wallclock times
		    // are always resolved:
		    HX_ASSERT(pTmpVal->isTimeResolved());
		}
		break;
	    default:
		HX_ASSERT(0);
		break;
	    } // /end switch(pTmpVal->m_type).
	}
    	m_pBeginTimeList->GetNext(lPos);
    } // /end while (lPos ...).

    // else time must already be set.
cleanup:
    return ret;
}

HX_RESULT
CSmilElement::setEndTime(CSmilParser* pParser)
{
    HX_RESULT ret = HXR_OK;

    BOOL bEndTimeHasBeenSet = FALSE;

    UINT32 ulOffset = 0;
    SmilTimeValue* pNextResolvedTimeValue = NULL;

    LISTPOSITION lPos = NULL;

    CHXSimpleList* pListOfAllResolvedEndTimes = new CHXSimpleList;
    // /Looks at all resolved end times in the list and
    // returns the SmilTimeValue with the closest time at or
    // later than the time passed in:
    HX_RESULT rettimeval = HXR_OK;
    rettimeval = getNextResolvedTimeValue(pNextResolvedTimeValue,
	    SMILTIME_NEGATIVE_INFINITY, SMILTIME_NEGATIVE_INFINITY,
	    SmilEndTimeList, pListOfAllResolvedEndTimes);
    // /NOTE: ret!=HXR_OK is NOT an error condition; it means
    // that no value in the end time list was found that was
    // resolved.
    
    if (SUCCEEDED(rettimeval) && NULL != pNextResolvedTimeValue)
    {
	if (pListOfAllResolvedEndTimes)
	{
	    // /Go through this list and insert each into the pending list:
	    LISTPOSITION lPosTmp =
		    pListOfAllResolvedEndTimes->GetHeadPosition();
	    while (lPosTmp)
	    {
		SmilTimeValue* pTmpVal = (SmilTimeValue*)
			pListOfAllResolvedEndTimes->GetAt(lPosTmp);
		if (pTmpVal  &&  pTmpVal->isTimeResolved()  &&
			pTmpVal->m_pElement)
		{
		    if (pTmpVal != pNextResolvedTimeValue)
		    {
			// /(?XXXEH- TODO: insert into list based on resolved
			// time?  end="20s;0s" works OK, so...?)
			if (pParser->EstablishEndTimeList())
			{
			    CHXSimpleList* pList =
				    pParser->GetPendingEndTimeList();
			    // /Don't add if it's a duplicate:
			    if (!pParser->isDuplicateEntry(pList, pTmpVal))
			    {
				pList->AddTail(pTmpVal);
			    }
			}
		    }
		}
		else
		{
		    HX_ASSERT(0  &&  "timeval invalid");
		}
    		pListOfAllResolvedEndTimes->GetNext(lPosTmp);
	    } // /end while(lPos...).
	}
	HX_DELETE(pListOfAllResolvedEndTimes);

	bEndTimeHasBeenSet = TRUE;
	HX_ASSERT(pNextResolvedTimeValue->isTimeResolved());
	switch (pNextResolvedTimeValue->m_type)
	{
	case SmilTimeOffset:
	case SmilTimeClockValue:
	    {
		// /XXXEH- is this what we really want to do?
		// Alternatively, we could have resolved-to "base" time
		// as 0 and then m_lOffset is added to get resolved-to
		// "offset" time:
		m_lEndOffset = pNextResolvedTimeValue->getTimeOffset();
		m_bEndOffsetSet = TRUE;
#if defined(_DEBUG) // /XXXEH- testing!:
		LONG32 lResolvedToTime = 0;
		HX_RESULT tmprslt =
			pNextResolvedTimeValue->getEffectiveResolvedTime(
			lResolvedToTime);
		HX_ASSERT(tmprslt==HXR_OK  &&
			m_lEndOffset == lResolvedToTime);
#endif
	    }
	    break;
	case SmilTimeSyncBase:
#if defined(ENABLE_SYNC_TO_PREV)
	case SmilTimeSyncToPrev:
#endif
	case SmilTimeEvent:
	    {
		// /NOTE: this's time must be *resolved* already which
		// shouldn't happen yet:
		HX_ASSERT(!pNextResolvedTimeValue->isTimeResolved());
	    }
	    break;
	case SmilTimeMediaMarker:
	    {
		//XXXEH- TODO: handle media markers:
		HX_ASSERT(0);
		//pParser->addEndMediaMarkerSyncElement(this);
	    }
	    break;
	case SmilTimeWallclock:
	    {
		// /XXXEH- wouldn't it be better to use
		// getEffectiveResolvedTime() here(?) so as to treat all time
		// types consistently?
		m_lEndOffset = pNextResolvedTimeValue->getTimeOffset();
		m_bEndOffsetSet = TRUE;
		m_bWallClockEnd = TRUE;
	    }
	    break;
	case SmilTimeNone:
	    break;
	} // /end switch(pNextResolvedTimeValue->m_type).
    }

    // /Now, go through all unresolved end times and add this element to
    // the appropriate list(s) for each unresolved time value found:
    if (m_pEndTimeList)
    {
	lPos = m_pEndTimeList->GetHeadPosition();
    }

    if (NULL == lPos) // /list is empty.
    {
	goto cleanup;
    }

    while (lPos  &&  HXR_OK == ret)
    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -