📄 smlelem.cpp
字号:
SmilTimeValue* pTmpVal = (SmilTimeValue*)m_pEndTimeList->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->addEndTimeSyncElement(this);
// /XXXEH- make sure we handle end="3s; prev.end" where
// both are valid times; the following doesn't handle this
// case:
if (!bEndTimeHasBeenSet)
{
m_EndEventSourceID = pTmpVal->m_idRef;
m_nEndEventSourceTag = pTmpVal->m_position;
// /XXXEH- wouldn't it be better to use
// getEffectiveResolvedTime() here(?) so as to treat
// all time types consistently?
m_lEndEventClockValue =
pTmpVal->getTimeOffset();
}
}
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->addEndTimeSyncElement(this);
// /XXXEH- make sure we handle end="3s; prev.end" where
// both are valid times; the following doesn't handle this
// case:
if (!bEndTimeHasBeenSet)
{
SMILNode* pSibling =
m_pNode->m_pParent->getFirstChild();
SMILNode* pLastNode = pSibling;
while (pSibling)
{
if (pSibling->m_id == m_pNode->m_id)
{
// we found our boy...
break;
}
pLastNode = pSibling;
pSibling = m_pNode->m_pParent->getNextChild();
}
HX_ASSERT(pSibling && pLastNode);
if (pSibling && pLastNode)
{
m_EndEventSourceID = pLastNode->m_id;
// /XXXEH- wouldn't it be better to use
// getEffectiveResolvedTime() here(?) so as to
// treat all time types consistently?
m_lEndEventClockValue =
pTmpVal->getTimeOffset();
m_nEndEventSourceTag =
pTmpVal->m_position;
}
else
{
ret = HXR_FAIL;
}
}
}
break;
#endif
case SmilTimeEvent:
{
pParser->addEndEventElement(pTmpVal);
}
break;
case SmilTimeMediaMarker:
{
pParser->addEndMediaMarkerSyncElement(pTmpVal);
}
break;
case SmilTimeWallclock:
{
// /We shouldn't ever get here because wallclock times
// are always resolved:
HX_ASSERT(pTmpVal->isTimeResolved());
}
break;
case SmilTimeNone:
break;
} // /end switch(pTmpVal->m_type).
}
m_pEndTimeList->GetNext(lPos);
} // /end while (lPos ...).
// else time must allready be set.
cleanup:
return ret;
}
HX_RESULT
CSmilElement::getEndTimeValue(REF(SmilTimeValue*) pValue)
{
HX_RESULT ret = HXR_OK;
// This function just returns the first value in the end-time list,
// even if that value is not yet resolved to a clock time:
// If you want to use the "right" value for a given time t, then
// call "getNextResolvedTimeValue()"
if (m_pEndTimeList)
{
LISTPOSITION pos = m_pEndTimeList->GetHeadPosition();
if (pos)
{
pValue = (SmilTimeValue*)m_pEndTimeList->GetAt(pos);
}
}
return ret;
}
HX_RESULT
CSmilElement::getBeginTimeValue(REF(SmilTimeValue*) pValue)
{
HX_RESULT ret = HXR_OK;
// This function just returns the first value in the begin-time list,
// even if that value is not yet resolved to a clock time:
// If you want to use the "right" value for a given time t, then
// call "getNextResolvedTimeValue()"
if (m_pBeginTimeList)
{
LISTPOSITION pos = m_pBeginTimeList->GetHeadPosition();
if (pos)
{
pValue = (SmilTimeValue*)m_pBeginTimeList->GetAt(pos);
}
}
return ret;
}
// /Returns HXR_OK except if the element has not ever been inserted in the
// timeline, in which case the return value is HXR_NOT_INITIALIZED.
// In this case, the value placed into ulActualStartTime will remain whatever
// is set in the delay value of the element. If the element has an
// indefinite begin time, SMIL_TIME_INFINITY is returned in ulActualStartTime
// with HXR_OK as the return value. Note that SMIL_TIME_INFINITY is not
// the same value as ((UINT32)-1) which is a possible return value and means
// that the value is not initialized:
HX_RESULT
CSmilElement::getCurrentScheduledStartTime(REF(ULONG32) ulActualStartTime)
{
HX_RESULT ret = HXR_OK;
ulActualStartTime = m_ulDelay;
BOOL bIsMediaObject = CSmilParser::isMediaObject(m_pNode);
if (!m_bHasBeenScheduled && bIsMediaObject)
{
ret = HXR_NOT_INITIALIZED;
}
else if (m_bIndefiniteBegin)
{
ulActualStartTime = SMILTIME_INFINITY;
}
else if (!bIsMediaObject && ulActualStartTime == ((UINT32) -1))
{
ret = HXR_NOT_INITIALIZED;
}
// /#define XXXEHODGE_DEBUG_PRINTF_CURRENTSCHEDULEDSTARTTIME
#if defined(_DEBUG) && defined(XXXEHODGE_DEBUG_PRINTF_CURRENTSCHEDULEDSTARTTIME)
{
static BOOL bFirstTime = TRUE;
FILE* f1 = ::fopen("c:\\smil2.txt", bFirstTime?"w":"a+");
::fprintf(f1, "\n[%s]->getCurrentScheduledStartTime() "
"ulActualStopTime := %lu (delay=%lu, dur=%lu, "
"beginOffsetFromSyncBase=%lu) \n", (const char*)m_pNode->m_id,
ulActualStartTime, m_ulDelay, m_ulDuration, m_ulBeginOffsetFromSyncBase);
::fclose(f1);
bFirstTime=FALSE;
}
#endif
return ret;
}
// /Returns HXR_OK except if the element has not ever been inserted in the
// timeline, in which case the return value is HXR_NOT_INITIALIZED.
// In this case, the value placed into ulActualStopTime will remain whatever
// is set in the delay value of the element. If the element has an
// indefinite end time, SMIL_TIME_INFINITY is returned in ulActualStopTime
// with HXR_OK as the return value. Note that SMIL_TIME_INFINITY is not
// the same value as ((UINT32)-1) which is a possible return value and means
// that the value is not initialized:
HX_RESULT
CSmilElement::getCurrentScheduledStopTime(REF(ULONG32) ulActualStopTime)
{
HX_RESULT ret = HXR_OK;
// /Fixes PR 63733: initialize to invalid time in case caller did not:
ulActualStopTime = (UINT32)-1;
if (m_bIndefiniteDuration || m_bIndefiniteEnd)
{
ulActualStopTime = SMILTIME_INFINITY;
}
// /Helps fix PR 53531 (unwinding after string of pauses) when
// m_ulDuration has not been updated to reflect the paused time so far:
else if (isPausedInExcl())
{
#if XXXEH_HANDLE_CASE_WHERE_RESOLVED_END_IS_NOW_IN_EFFECT
#else
ulActualStopTime = SMILTIME_PAUSED_INDEFINITELY;
#endif
}
else if (isStoppedInExcl())
{
ulActualStopTime = m_ulStopTimeInExcl;
}
else if (isDeferredInExcl())
{
ulActualStopTime = SMILTIME_DEFERRED_INDEFINITELY;
}
else if (m_ulDelay != ((UINT32) -1) &&
m_ulDuration != ((UINT32) -1))
{
if (m_bBeginOffsetSet)
{
LONG32 lBeginOffsetPast0 = m_lBeginOffset;
if (m_lBeginOffset < 0)
{
lBeginOffsetPast0 = 0;
}
ulActualStopTime = m_ulDelay + m_ulDuration - lBeginOffsetPast0;
}
else
{
if (m_bCurBeginIsOffsetFromSyncBase)
{
ulActualStopTime = m_ulDelay + m_ulDuration;
// /Adding this if() check fixes hide-site problems exposed
// in the repro case for PR 53531 once 53531 had been fixed;
// this makes sure that the beginOffsetFromSyncBase is
// accounted for only when it should be. Fixes
// BUG-20010619_lastExclChildGetsItsOffsetFromSyncbaseIgnored.smil
if (m_bDurationIncludesDelayBeyondSyncbase)
{
ulActualStopTime -= m_ulBeginOffsetFromSyncBase;
}
}
else
{
ulActualStopTime = m_ulDelay + m_ulDuration;
}
}
}
else if (m_ulDelay != (UINT32)-1 && m_bCurrentSourceIsLive)
{
// /Fix for PR 57230:
// live sources that have 0 dur, which means they play
// forever, should have infinity, not 0, used as
// their dur when calculating whether or not they're
// visible at the current time:
ulActualStopTime = (UINT32)SMILTIME_INFINITY;
}
else
{
ret = HXR_NOT_INITIALIZED;
}
// /#define XXXEHODGE_DEBUG_PRINTF_CURRENTSCHEDULEDSTOPTIME
#if defined(_DEBUG) && defined(XXXEHODGE_DEBUG_PRINTF_CURRENTSCHEDULEDSTOPTIME)
{
static BOOL bFirstTime = TRUE;
FILE* f1 = ::fopen("c:\\smil2.txt", bFirstTime?"w":"a+");
::fprintf(f1, "\n[%s]->getCurrentScheduledStopTime() "
"ulActualStopTime := %lu (delay=%lu, dur=%lu, "
"beginOffsetFromSyncBase=%lu) \n", (const char*)m_pNode->m_id,
ulActualStopTime, m_ulDelay, m_ulDuration, m_ulBeginOffsetFromSyncBase);
::fclose(f1);
bFirstTime=FALSE;
}
#endif
return ret;
}
// /This function takes a time as input and returns in pValue the begin
// or end time (depending on listType) that makes the most
// sense given the time passed in; it assumes times that are
// resolvable have already been resolved (and thus their m_bIsResolved
// is TRUE), and it thus ignores unresolved times. It returns
// HXR_FAILED and sets pValue to NULL if no now-or-future resolved begin
// time is found.
// NOTE!!!: this will NOT return the currently-active time if the element
// is already playing at lCurTime since it would be in the past. The
// currently-active begin and end times can be found in this->m_lBeginOffset
// or this->m_lEndOffset, respectively, and that those values are only
// valid if m_bBeginOffsetSet and m_bEndOffsetSet, respectively, are TRUE:
// Also Note: pValue, as well as the two lists, is|are filled with either
// begin or end time|times, depending on the listType value:
HX_RESULT
CSmilElement::getNextResolvedTimeValue(REF(SmilTimeValue*) pValue,
INT32 lCurTimeInGroupTime,
INT32 lCurTimeInSyncBaseTime,
SmilTimingListType listType,
CHXSimpleList* pListOfAllResolvedTimes)
{
HX_RESULT retval = HXR_OK;
SmilTimeValue* pTmpVal = NULL;
SmilTimeValue* pTimeValFoundSoFar = NULL;
CHXSimpleList* pWhichList = NULL;
LONG32 lCurTimeInSameTimeSpace = lCurTimeInSyncBaseTime;
LONG32 lCurUsableTimeInGroupTime = lCurTimeInGroupTime;
// /If group time is not known, use sync-base time:
if (SMILTIME_NEGATIVE_INFINITY == lCurTimeInGroupTime)
{
lCurUsableTimeInGroupTime = lCurTimeInSyncBaseTime;
}
LISTPOSITION lPos = NULL;
if (SmilBeginTimeList == listType) // /get begin time:
{
pWhichList = m_pBeginTimeList;
}
else if (SmilEndTimeList == listType)// /get end time:
{
pWhichList = m_pEndTimeList;
}
else
{
HX_ASSERT(SmilBeginTimeList == listType ||
SmilEndTimeList == listType);
}
if (NULL == pWhichList)
{
retval = HXR_FAILED;
goto cleanup;
}
lPos = pWhichList->GetHeadPosition();
if (NULL == lPos) // /list is empty.
{
retval = HXR_FAILED;
goto cleanup;
}
// /The following loop simply finds the time that is nearest
// to, but not earlier than, lCurTime:
// *Which* curTime depends on the type; events resolve to group times,
// while clockValues resolve to syncBase times:
while (lPos && HXR_OK == retval)
{
pTmpVal = (SmilTimeValue*)pWhichList->GetAt(lPos);
if (pTmpVal)
{
if (!pTmpVal->isTimeResolved())
{
pWhichList->GetNext(lPos);
continue;
}
// /It's resolved, so insert it:
if (pListOfAllResolvedTimes)
{
pListOfAllResolvedTimes->AddTail(pTmpVal);
}
LONG32 lResolvedToTimeOfTimeValFoundSoFar =SMILTIME_INFINITY;
HX_RESULT tmprslt = HXR_OK;
if (NULL != pTimeValFoundSoFar)
{
// /We want to use pTimeValFoundSoFar, not pTmpVal here!
// Fixes case where there are two or more resolved times and
// the first, lexically, is higher than any of the others:
tmprslt = pTimeValFoundSoFar->getEffectiveResolvedTime(
lResolvedToTimeOfTimeValFoundSoFar);
HX_ASSERT(HXR_OK == tmprslt);
if (!SUCCEEDED(tmprslt))
{
HX_ASSERT(SUCCEEDED(tmprslt));
continue;
}
}
switch (pTmpVal->getTimeType())
{
case SmilTimeMediaMarker:
case SmilTimeWallclock:
case SmilTimeEvent:
lCurTimeInSameTimeSpace = lCurUsableTimeInGroupTime;
break;
case SmilTimeOffset:
case SmilTimeClockValue:
case SmilTimeSyncBase:
default:
lCurTimeInSameTimeSpace = lCurTimeInSyncBaseTime;
break;
}
switch (pTmpVal->getTimeType())
{
case SmilTimeNone:
break; // /Skip this time.
case SmilTimeWallclock:
case SmilTimeOffset:
case SmilTimeClockValue:
{
LONG32 lEffectiveResolvedToTime = 0;
tmprslt = pTmpVal->getEffectiveResolvedTime(
lEffectiveResolvedToTime);
#if defined(_DEBUG) // /XXXEH- testing!:
LONG32 lTimeOffset = pTmpVal->getTimeOffset();
HX_ASSERT(tmprslt==HXR_OK &&
lTimeOffset == lEffectiveResolvedToTime);
#endif
// /XXXEH- TODO: add bool (& time val?) that says if (& when) this begin time
// was already used; if already used, don't use it again, and seeks and
// repeats must erase this bool (& time val); this is especially needed
// if we start treating all times as events, i.e., consistently:
// /Only use times that are now or later:
if (lEffectiveResolvedToTime >= lCurTimeInSameTimeSpace)
{
if (NULL == pTimeValFoundSoFar ||
lEffectiveResolvedToTime <
lResolvedToTimeOfTimeValFoundSoFar)
{
pTimeValFoundSoFar = pTmpVal;
}
}
}
break;
case SmilTimeMediaMarker:
case SmilTimeSyncBase:
#if defined(ENABLE_SYNC_TO_PREV)
case SmilTimeSyncToPrev:
#endif
case SmilTimeEvent:
{
// /XXXEH- TODO: finish this, and make sure m_lResolvedToTime and m_lWhenTimeWasResolved are being set:
LONG32 lEffectiveResolvedToTime = 0;
HX_RESULT tmprslt2 = pTmpVal->
getEffectiveResolvedTime(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -