📄 smlelem.cpp
字号:
lEffectiveResolvedToTime);
HX_ASSERT(SUCCEEDED(tmprslt2));// /Should be resovled.
if (SUCCEEDED(tmprslt2) &&
lEffectiveResolvedToTime >= lCurTimeInSameTimeSpace)
{
LONG32 lTimeOffset = pTmpVal->getTimeOffset();
if (lEffectiveResolvedToTime <
// /XXXEH- TODO: add +offset since this is an event-based time; need
// "timecmp(x,y)" function that compares two SmilTimeValues (taking into
// account that negative offsets shouldn't be compared if this is an event
// time) and returns -1 if x is greater, 0 if same, +1 if y is later:
// /XXXEH- TODO: argue the following with W3C SYMM Smil Boston Working
// Group: if we treat event-based times with negative offset as "now"
// w/clip-begin, then why not same for sync-base (and other) values whose
// times are in the past when they first become resolved (e.g., clipped by
// parent, or sync-arc to event-arc'd time)? For example:
// <par>
// <ref id="x" begin="foo.activate" />
// <par begin="10s">
// <!-- resolves 3s after it's intended value: -->
// <ref begin="x.begin-3s"/>
lResolvedToTimeOfTimeValFoundSoFar)
{
pTimeValFoundSoFar = pTmpVal;
}
// /XXXEH- TODO: verify that this is how the
// SMIL Boston draft ends up dealing with the
// begin="x.focusInEvent-5s; x.focusInEvent-3s"
// issue:
// /Take the one with the earliest offset if
// the resolved time is the same, so
// "x.focusInEvent-5s" beats out "x.focusInEvent",
// and "x.focusInEvent" beats out "x.focusInEvent+2s"
// /XXXEH- I think restart might play into this
// so that x.focusInEvent-5s would be used over
// x.focusInEvent-3s if and only if (restart=="never"
// OR (restart!="never" AND this's dur <=2s)):
else if (lEffectiveResolvedToTime ==
lResolvedToTimeOfTimeValFoundSoFar &&
lTimeOffset <
pTimeValFoundSoFar->getTimeOffset())
{
pTimeValFoundSoFar = pTmpVal;
}
}
}
break;
}
}
pWhichList->GetNext(lPos);
} // /end while(lPos...).
pValue = pTimeValFoundSoFar;
if (NULL == pValue)
{
retval = HXR_FAILED;
}
cleanup:
return retval;
}
HX_RESULT
CSmilElement::resolveEventTimeValues(INT32 lCurTime,
const char* pEventName,
const char* pEventElementId,
SmilTimingListType listType,
REF(BOOL) bATimeWasResolved)
{
HX_RESULT retval = HXR_OK;
SmilTimeValue* pValue = NULL;
CHXSimpleList* pWhichList = NULL;
bATimeWasResolved = FALSE;
LISTPOSITION lPos = NULL;
if (NULL == pEventName ||
// /pEventElementId can be NULL but not non-NULL and empty:
(pEventElementId && '\0' == *pEventElementId) )
{
retval = HXR_FAILED;
goto cleanup;
}
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;
}
// /XXXEH- is there any reason we should start from tail instead?
lPos = pWhichList->GetHeadPosition();
if (NULL == lPos) // /list is empty.
{
retval = HXR_FAILED;
goto cleanup;
}
while (lPos && HXR_OK == retval)
{
pValue = (SmilTimeValue*)pWhichList->GetAt(lPos);
// /If this begin or end time is a time event based on this event
// from the element with pEventElementId, then we can (and do)
// resolve it here:
if(NULL!= pValue && (SmilTimeEvent == pValue->m_type ||
(pValue->m_bTreatSyncArcAsEvent &&
pValue->isSyncBaseTimeVal()) ) )
{
// /Now, see if we've got an element that is waiting for this
// event from the pEventElement:
if (!pValue->getIdRef() || !pValue->getEventName())
{
HX_ASSERT(pValue->getIdRef() && pValue->getEventName());
pWhichList->GetNext(lPos);
continue;
}
if ((!pEventElementId || strcmp(pValue->getIdRef(),
pEventElementId) == 0) &&
strcmp(pValue->getEventName(), pEventName) == 0 )
{
BOOL bIsResolvedAlready = pValue->isTimeResolved();
INT32 lProirResolvedToTime = (bIsResolvedAlready?
pValue->getResolvedToTimeWithoutOffset():-1);
pValue->setIsTimeResolved(TRUE);
pValue->setResolvedToTime(lCurTime);
pValue->setWhenTimeWasResolved(lCurTime);
// /[Optimization]: In case we get called twice with the
// same event at the same resolved time, let's not force
// a stop/start of the element:
if (!bIsResolvedAlready || lCurTime !=lProirResolvedToTime)
{
bATimeWasResolved = TRUE;
}
}
}
pWhichList->GetNext(lPos);
} // /end while(lPos...).
cleanup:
return retval;
}
// /This method goes through the m_pEndTimeList to see if there's an
// event-arc end time or other unresolved end time; this is important
// for use in the algorithm for determining whether or not something
// should restart (see SMIL 2.0 Spec Timing Module's getNextInterval()
// pseudocode):
BOOL
CSmilElement::hasUnresolvedEndTime()
{
BOOL bHasUnresolvedEndTime = FALSE;
SmilTimeValue* pValue = NULL;
LISTPOSITION lPos = NULL;
if (NULL == m_pEndTimeList)
{
goto cleanup;
}
// /XXXEH- is there any reason we should start from tail instead?
lPos = m_pEndTimeList->GetHeadPosition();
if (NULL == lPos) // /list is empty.
{
goto cleanup;
}
while (lPos && !bHasUnresolvedEndTime)
{
pValue = (SmilTimeValue*)m_pEndTimeList->GetAt(lPos);
if(NULL == pValue)
{
m_pEndTimeList->GetNext(lPos);
continue;
}
if (SmilTimeEvent == pValue->m_type)
{
bHasUnresolvedEndTime = TRUE;
}
// /XXXEH- TODO: need to go through sync-arc element and see
// if *it* has any unresolved time(s) (begin or end, depending
// on this sync-arc time's position value) and, if not, then
// DON'T claim bHasUnresolvedEndTime is TRUE:
else if (pValue->m_bTreatSyncArcAsEvent &&
pValue->isSyncBaseTimeVal())
{
if (!pValue->isTimeResolved())
{
bHasUnresolvedEndTime = TRUE;
}
}
m_pEndTimeList->GetNext(lPos);
} // /end while(lPos...).
cleanup:
return bHasUnresolvedEndTime;
}
// /This method returns the pure duration from the media's begin to its
// end, w/o any delay included:
ULONG32
CSmilElement::getPureDuration()
{
HX_ASSERT(!m_bDurationIncludesDelayBeyondSyncbase ||
m_bCurBeginIsOffsetFromSyncBase);
if (m_bDurationIncludesDelayBeyondSyncbase)
{
return (m_ulDuration - m_ulBeginOffsetFromSyncBase);
}
else
{
return m_ulDuration;
}
/*
return (m_bDurationIncludesDelayBeyondSyncbase?
m_ulDuration-m_ulBeginOffsetFromSyncBase : m_ulDuration);
*/
}
HX_RESULT
CSmilElement::resolveSyncArcTimeValues(INT32 lResolvedToTime,
const char* pSyncBaseElementId,
SmilTimingListType listType,
REF(BOOL) bATimeWasResolved,
BOOL bMoveNewlyResolvedsToPendingTimesList,
CSmilParser* pParser)
{
HX_RESULT retval = HXR_OK;
SmilTimeValue* pValue = NULL;
CHXSimpleList* pWhichList = NULL;
bATimeWasResolved = FALSE;
LISTPOSITION lPos = NULL;
if (NULL == pSyncBaseElementId)
{
retval = HXR_FAILED;
goto cleanup;
}
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;
}
// /XXXEH- is there any reason we should start from tail instead?
lPos = pWhichList->GetHeadPosition();
if (NULL == lPos) // /list is empty.
{
retval = HXR_FAILED;
goto cleanup;
}
while (lPos && HXR_OK == retval)
{
pValue = (SmilTimeValue*)pWhichList->GetAt(lPos);
// /If this begin or end time is a time event based on this event
// from the element with pSyncBaseElementId, then we can (and do)
// resolve it here:
if(NULL!= pValue && pValue->isSyncBaseTimeVal())
{
// /Now, see if we've got an element that is waiting for this
// event from the pEventElement:
if (!pValue->getIdRef())
{
HX_ASSERT(pValue->getIdRef());
pWhichList->GetNext(lPos);
continue;
}
if (strcmp(pValue->getIdRef(), pSyncBaseElementId) == 0)
{
// /Helps fix SMIL 2.0 Interop Timing #15.13:
// if we're resuming a paused element and its duration thus
// got extended, don't re-resolve (and re-insert) other
// elements who are sync-arc'd to the *begin* time of this
// resumed element:
if (pValue->isTimeResolved() && lResolvedToTime ==
pValue->getResolvedToTimeWithoutOffset() &&
SmilBeginTimeList == listType)
{
bMoveNewlyResolvedsToPendingTimesList = FALSE;
}
pValue->setIsTimeResolved(TRUE);
pValue->setResolvedToTime(lResolvedToTime);
// /XXXEH- this shouldn't matter what we put here, but
// we *should* fill this with the current time:
pValue->setWhenTimeWasResolved(0);
bATimeWasResolved = TRUE;
if (pParser && bMoveNewlyResolvedsToPendingTimesList)
{
if (SmilBeginTimeList == listType)
{
if (pParser->EstablishBeginTimeList())
{
CHXSimpleList* pList =
pParser->GetPendingBeginTimeList();
// /Don't add if it's a duplicate:
if (!pParser->isDuplicateEntry(pList, pValue))
{
pList->AddTail(pValue);
}
}
}
else
{
if (pParser->EstablishEndTimeList())
{
CHXSimpleList* pList =
pParser->GetPendingEndTimeList();
// /Don't add if it's a duplicate:
if (!pParser->isDuplicateEntry(pList, pValue))
{
pList->AddTail(pValue);
}
}
}
}
}
}
pWhichList->GetNext(lPos);
} // /end while(lPos...).
cleanup:
return retval;
}
// /Returns HXR_FAILED if element or its parent don't exist. The spec says
// that "always" is what is to be used for restart and restartDefault for the
// element if it has no parent or the parent has no restartDefault value:
HX_RESULT
CSmilElement::getParentRestartDefault()
{
HX_RESULT ret = HXR_OK;
if (NULL == m_pNode)
{
ret = HXR_FAILED;
}
else
{
SMILNode* pParent = m_pNode->m_pParent;
if (!pParent || !pParent->m_pElement)
{
ret = HXR_FAILED;
}
else
{
switch (pParent->m_pElement->m_restartDefaultBehavior)
{
case SmilRestartNever:
case SmilRestartWhenNotActive:
case SmilRestartAlways:
// /Both restartDefault and restart behavior are assigned
// to parent's restartDefault behavior:
m_restartDefaultBehavior =
m_restartBehavior =
pParent->m_pElement->m_restartDefaultBehavior;
break;
case SmilRestartInherit:
m_restartDefaultBehavior =
m_restartBehavior = SmilRestartAlways;
break;
default:
HX_ASSERT(0);
break;
}
}
}
return ret;
}
void CSmilElement::updateRemoveTime(UINT32 ulRemoveTime)
{
m_ulRemoveTime = ulRemoveTime;
if (m_pHandler)
{
m_pHandler->handleRemoveTimeUpdate(this, ulRemoveTime);
}
}
void CSmilElement::handleXMMF(const char* pszID, const char* pszXMMFile, const char* pszSrc)
{
if (m_pHandler)
{
m_pHandler->handleExternalMediaMarkerFile(this,
pszID,
pszXMMFile,
pszSrc);
}
}
BOOL CSmilElement::hasEventBasedBeginTime()
{
BOOL bRet = FALSE;
if (m_pBeginTimeList)
{
LISTPOSITION pos = m_pBeginTimeList->GetHeadPosition();
while (pos)
{
SmilTimeValue* pValue =
(SmilTimeValue*) m_pBeginTimeList->GetNext(pos);
if (pValue &&
pValue->m_type == SmilTimeEvent)
{
bRet = TRUE;
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -