📄 smltime.cpp
字号:
if ((UINT32)-1 != ulTimeFinished)
{
if (m_pSourceElement && (UINT32)-1==m_pSourceElement->m_ulDuration)
{
if (m_bDelaySet)
{
if (ulTimeFinished > m_pSourceElement->m_ulDelay)
{
ulTimeFinished -= m_pSourceElement->m_ulDelay;
}
else
{
ulTimeFinished = 0;
}
}
pnr = HXR_OK;
setDuration(ulTimeFinished, FALSE);
}
}
return pnr;
}
void
// /XXXEH- TODO: [20010411] we need to get more information about *what* just
// got resolved so we don't re-resolve the m_pSourceElement on something
// that it already has resolved. For instance, if the duration of
// pEventElement changed, we only want to resolve or re-resolve
// m_pSourceElement's begin and/or end time that are based on the *end* of
// the event element, and leave be its sync-arcs that are based on the
// *begin* of the event element.
// /XXXEH- TODO: [20010411] Don't set m_bBeginOffsetSet and other vars here;
// wait until the begin|end list is evaluated to get the current
// instance begin|end time (which may not be the sync arc that gets
// resolved herein). Also, do this for par|seq|excl::elementResolved
CSmilTimelineElement::elementResolved(CSmilTimelineElement* pEventElement)
{
UINT32 ulPriorPureDuration = m_pSourceElement->getPureDuration();
BOOL bIsPlayableObjectNotInsertedInTimeline = FALSE;
if (!pEventElement->m_pSourceElement ||
(pEventElement->m_pSourceElement->m_pNode &&
(m_pParser->isMediaObject(
pEventElement->m_pSourceElement->m_pNode) ||
m_pParser->isNonMediaPlayableObject(
pEventElement->m_pSourceElement->m_pNode) ) &&
!pEventElement->m_pSourceElement->m_bInsertedIntoTimeline) )
{
bIsPlayableObjectNotInsertedInTimeline = TRUE;
}
// /Fixes SMIL 2.0 Interop Timing #28.2 (which is PR 52571):
// If eventElement can't begin because it begins and ends before its
// parent begins, then don't propagate its time to other elements:
if (pEventElement->m_pSourceElement->m_bBeginOffsetSet &&
pEventElement->m_pSourceElement->m_lBeginOffset < 0)
{
if (0 == pEventElement->m_pSourceElement->m_ulDuration)
{
return;
}
}
BOOL bNeedToResolveBeginTimeListVals = FALSE;
BOOL bNeedToResolveEndTimeListVals = FALSE;
BOOL bWasInsertedOntoTimeline = FALSE;
BOOL bIsInExcl = m_pParser->hasAncestor(SMILExcl,
m_pSourceElement->m_pNode);
BOOL bPreviousDelaySetVal = m_bDelaySet;
BOOL bUseBeginOffsetForPendingBeginList = FALSE;;
// /If we are in an excl and we are beginning after our excl parent's
// current child-derived end, then go ahead and insert into the timeline,
// else see all "We need to go through ..." notes, below. This fixes
// Interop Timing cases #9.35 & 9.36 (that broke while fixing 15.13):
// Note that we don't want to insert ANY element that begins after its
// parent's immutable end time):
BOOL bCantExtendParentDuration = FALSE;
ULONG32 ulParentEnd = (UINT32)-1;
SMILNode* pSyncBaseNode = m_pParser->getSyncAncestor(
m_pSourceElement->m_pNode);
LONG32 lSourceElementDelayAdjustmentToSyncBaseTime = 0;
if (pSyncBaseNode && pSyncBaseNode->m_pElement)
{
// /XXXEH- TODO: handle case where endsync is SMILEventSourceID and
// id matches m_pSourceElement->m_pNode->m_id:
// /XXXEH- TODO: also handle when sync parent has indefinite end|dur:
if (!pSyncBaseNode->m_pElement->m_bHasExplicitEnd &&
!pSyncBaseNode->m_pElement->m_bHasExplicitDur &&
(SMILEventSourceFirst !=
pSyncBaseNode->m_pElement->m_nEndsyncEventSourceTag &&
SMILEventSourceID !=
pSyncBaseNode->m_pElement->m_nEndsyncEventSourceTag) )
{
bCantExtendParentDuration = FALSE;
if ((UINT32)-1 != pSyncBaseNode->m_pElement->m_ulDuration &&
(UINT32)-1 != pSyncBaseNode->m_pElement->m_ulDelay)
{
ulParentEnd = pSyncBaseNode->m_pElement->m_ulDelay +
pSyncBaseNode->m_pElement->m_ulDuration;
}
}
else
{
bCantExtendParentDuration = TRUE;
if (bIsPlayableObjectNotInsertedInTimeline)
{
// /Fixes BUG-20010423_nothingShouldPlay_beginBasedOn....smi:
// If eventElement begins after its parent ends, then don't
// propagate its time to other elements:
if ((UINT32)-1 == pEventElement->m_pSourceElement->m_ulDelay ||
pEventElement->m_pSourceElement->m_ulDelay >=
pSyncBaseNode->m_pElement->m_ulDelay +
pSyncBaseNode->m_pElement->m_ulDuration)
{
return; // /Starts too late.
}
}
}
}
//First, let's see if we have a begin event to resolve:
if(m_pSourceElement->m_nBeginEventSourceTag == SMILEventSourceBegin &&
m_pSourceElement->m_BeginEventSourceID == pEventElement->m_pID)
{
if(pEventElement->m_bDelaySet)
{
// /Be sure not to overflow using ULONGs since
// beginEventClockValue might be negative:
LONG32 lDelay =
(LONG32)pEventElement->m_pSourceElement->m_ulDelay +
m_pSourceElement->m_lBeginEventClockValue;
// /Fixes SMIL 2.0 Interop Timing #28.1 and others that have
// sync-arc to an element with a negative begin time:
if (pEventElement->m_pSourceElement->m_bBeginOffsetSet &&
pEventElement->m_pSourceElement->m_lBeginOffset < 0)
{
lDelay += pEventElement->m_pSourceElement->m_lBeginOffset;
}
// /Fixes PR 82736 (begin=x.being... case) where sync-arc begin
// results in negative offset from parent and we've already
// adjusted for that:
else if (pSyncBaseNode->m_pElement->m_ulDelay > lDelay &&
// /If already inserted, then adjustForNegativeOffset()
// won't re-do any adjustment:
m_pSourceElement->m_bInsertedIntoTimeline &&
!m_pSourceElement->m_bIsRestarting)
{
// /Don't go earlier than synbase:
lDelay = pSyncBaseNode->m_pElement->m_ulDelay;
}
m_bDelaySet = TRUE;
m_pSourceElement->m_ulDelay = lDelay<0? 0: (ULONG32)lDelay;
if (lDelay < 0)
{
UINT32 ulDiff = (UINT32)(-lDelay);
// /If clip-begin is invalid, set it otherwise add to orig:
m_pSourceElement->m_ulClipBegin = ((UINT32)-1 ==
m_pSourceElement->m_ulAuthoredClipBegin? ulDiff :
ulDiff+m_pSourceElement->m_ulAuthoredClipBegin);
// /logicChange_test.smi: check if -1 before subtracting delay!:
if ((UINT32)-1 != m_pSourceElement->m_ulDuration)
{
if (m_pSourceElement->m_ulDuration > ulDiff)
{
m_pSourceElement->m_ulDuration -= ulDiff;
}
// /else duration is negative; it can't ever play.
else
{
m_pSourceElement->m_ulDuration = 0;
}
}
}
// /Now, if our begin delay (not offset) is based on a syncArc,
// we need to adjust our dur by the difference between our delay
// and our syncBase element's delay:
if ((UINT32)-1 != m_pSourceElement->m_ulDuration &&
m_pSourceElement->m_bEndOffsetSet &&
WAY_IN_THE_FUTURE != m_pSourceElement->m_ulDuration)
{
LONG32 lSum = m_pSourceElement->m_lEndOffset;
// /We need to remove our delay or it will get counted twice
lSum -= m_pSourceElement->m_ulDelay;
HX_ASSERT(lSum >= 0 && "ehodge: handle neg delay propogation");
m_pSourceElement->m_ulDuration = (UINT32)(lSum<0 ? 0 : lSum);
// /Fixes PR 80371: If our duration was set before and is now
// re-resolving, make sure the following flag is reset to false
// in case it wasn't before, otherwise show/hide code will
// subtract the delay from a duration that doesn't include the
// delay:
m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase = FALSE;
}
bNeedToResolveBeginTimeListVals = TRUE;
if (HXR_OK == m_pParser->adjustForNegativeOffset(m_pID))
{
if (!m_pSourceElement->m_bHasBeenScheduled ||
// /Helps fix PR 50588: if restarting, hasBeenSched
// will still be true, so check if inserted instead:
(m_pSourceElement->m_bIsRestarting &&
!m_pSourceElement->m_bInsertedIntoTimeline) )
{
// /We need to go through the proper channels if we're
// in an excl; a priorityClass may prevent us from
// starting or may defer our start, so just add us to
// the pending begin time list (unless we're extending
// the end of our excl parent, as described above):
// /First, see if our delay is beyond our parent's end:
BOOL bDelayIsBeyondParentEnd = FALSE;
if ((UINT32)-1 != ulParentEnd)
{
bDelayIsBeyondParentEnd =
(m_pSourceElement->m_ulDelay > ulParentEnd);
}
BOOL bInsertElement = bIsInExcl?
(bDelayIsBeyondParentEnd &&
!bCantExtendParentDuration) :
( !(bDelayIsBeyondParentEnd &&
bCantExtendParentDuration) );
// /But hold on: if parent's delay isn't yet resolved,
// then we can't be inserted until it resolves. Found
// this while fixing long-sync-arc bug PR 64498, par test:
// "..._longSyncArcBug-ParWithoutDur...sync.smil":
BOOL bParentDelayIsUnresolved = FALSE;
if ((UINT32)-1 == pSyncBaseNode->m_pElement->m_ulDelay ||
(pSyncBaseNode->m_pElement->m_pTimelineElement &&
pSyncBaseNode->m_pElement->m_pTimelineElement->m_bDelayEvent &&
!pSyncBaseNode->m_pElement->m_pTimelineElement->m_bDelaySet ))
{
bInsertElement = FALSE;
bParentDelayIsUnresolved = TRUE;
}
if (m_pSourceElement->m_bBeginOffsetSet)
{
// /If it's already been set, then just add this
// newly-resolved begin time to the pending queue
// and let it get sorted out there. This can
// happen with begin="0s; foo.begin"
bInsertElement = FALSE;
}
if (!bInsertElement)
{
// /We need to maintain old "delaySet" value so
// setDelay() call in eventual call to
// checkPendingBeginAndEndTimes() can insert this
// timeline element properly:
m_bDelaySet = bPreviousDelaySetVal;
// /Fixes PR 64498: flag the fact that long sync-arc
// begin is resolving before parent begin is resolved:
if (bParentDelayIsUnresolved)
{
m_pSourceElement->
m_bAwaitingSyncAncestorBeginNotification = TRUE;
m_pSourceElement->m_ulLongSyncArcBeginInGroupTime =
lDelay;
}
// /This else-if is the final fix for PR 64499: if
// sync-base has multiple begin times, then we also
// need to prepare for that event restarting it even
// though its first begin is already resolved:
else if (pSyncBaseNode->m_pElement->m_pBeginTimeList &&
pSyncBaseNode->m_pElement->m_pBeginTimeList->
GetCount() > 1)
{
m_pSourceElement->m_ulLongSyncArcBeginInGroupTime =
lDelay;
}
else
{
m_pSourceElement->m_ulLongSyncArcBeginInGroupTime =
(UINT32)-1;
}
}
else
{
bWasInsertedOntoTimeline = TRUE;
m_pSourceElement->m_ulLongSyncArcBeginInGroupTime =
(UINT32)-1;
m_pParser->insertTimelineElement(m_pID,
m_pSourceElement->m_ulDelay);
}
}
}
}
}
else if(m_pSourceElement->m_nBeginEventSourceTag == SMILEventSourceEnd &&
m_pSourceElement->m_BeginEventSourceID == pEventElement->m_pID &&
// /Helps fix SMIL 2.0 Interop Timing #28.9 where end as set by parent
// was being used when element's end was actually indefinite (or any
// value greater than parent's end); that truncated end time should
// not propogate; only the pre-truncated time (if any) should be used:
(!pEventElement->m_pSourceElement->m_bCurEndClippedByParent) )
{
// /If event element's duration is "WAY_IN_THE_FUTURE" then it's
// essentially an unresolved end time, so we should not resolve
// based on it:
if(pEventElement->m_bDurationSet && WAY_IN_THE_FUTURE !=
pEventElement->m_pSourceElement->m_ulDuration )
{
ULONG32 ulPriorDelay = m_pSourceElement->m_ulDelay;
m_bDelaySet = TRUE;
// /Be sure not to overflow using ULONGs since
// beginEventClockValue might be negative:
LONG32 lDelay =
(LONG32)pEventElement->m_pSourceElement->m_ulDuration +
m_pSourceElement->m_lBeginEventClockValue;
// /If delay is not set, don't add it!:
if(pEventElement->m_bDelaySet)
{
lDelay += (LONG32)pEventElement->m_pSourceElement->m_ulDelay;
// /Fixes case where dur already accounts for begin offset
// that's already built into the delay (e.g., begin="x.end-5"
// where x has an explicit begin offset greater than zero):
// /Helps fix PR 82736 (=x.begin case) by looking at flag and
// not just blindly assuming beginOffset is included in
// eventElement's m_ulDuration:
if (pEventElement->m_pSourceElement->
m_bDurationIncludesDelayBeyondSyncbase)
{
HX_ASSERT((UINT32)-1 != pEventElement->m_pSourceElement->
m_ulBeginOffsetFromSyncBase);
if ((UINT32)-1 != pEventElement->m_pSourceElement->
m_ulBeginOffsetFromSyncBase)
{
lDelay -= (LONG32)pEventElement->m_pSourceElement->
m_ulBeginOffsetFromSyncBase;
}
}
// /Fixes case where third ref has begin="second.end" and
// second has begin="first.end" where first.end is > 0.
// In that case, begin offset won't be set but delay WILL
// alread be part of the duration:
else if (pEventElement->m_pSourceElement->m_ulDelay >
pSyncBaseNode->m_pElement->m_ulDelay)
{
ULONG32 ulDelayFromSyncBase =
pEventElement->m_pSourceElement->m_ulDelay -
pSyncBaseNode->m_pElement->m_ulDelay;
HX_ASSERT(lDelay>(LONG32)ulDelayFromSyncBase);
if (lDelay < (LONG32)ulDelayFromSyncBase)
{
ulDelayFromSyncBase = lDelay;
}
lDelay -= (LONG32)ulDelayFromSyncBase;
}
}
// /Fixes PR 82736 (begin=x.end... case) where sync-arc begin
// results in negative offset from parent and we've already
// adjusted for that:
if (pSyncBaseNode->m_pElement->m_ulDelay > lDelay &&
// /If already inserted, then adjustForNegativeOffset()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -