smltime.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:225k
- /* ***** BEGIN LICENSE BLOCK *****
- * Source last modified: $Id: smltime.cpp,v 1.3.4.2 2004/07/13 23:02:47 ehodge Exp $
- *
- * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file,
- * are subject to the current version of the RealNetworks Public
- * Source License (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the current version of the RealNetworks Community
- * Source License (the "RCSL") available at
- * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
- * will apply. You may also obtain the license terms directly from
- * RealNetworks. You may not use this file except in compliance with
- * the RPSL or, if you have a valid RCSL with RealNetworks applicable
- * to this file, the RCSL. Please see the applicable RPSL or RCSL for
- * the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL") in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your version of
- * this file only under the terms of the GPL, and not to allow others
- * to use your version of this file under the terms of either the RPSL
- * or RCSL, indicate your decision by deleting the provisions above
- * and replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient may
- * use your version of this file under the terms of any one of the
- * RPSL, the RCSL or the GPL.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the
- * portions it created.
- *
- * This file, and the files included with this file, is distributed
- * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
- * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
- * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
- * ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- // system
- #include <time.h>
- // include
- #include "hxtypes.h"
- #include "hxwintyp.h"
- #include "hxcom.h"
- #include "hxxml.h"
- #include "smiltype.h"
- // pncont
- #include "hxslist.h"
- #include "hxmap.h"
- // pnmisc
- #include "hxwinver.h"
- // rnxmllib
- #include "hxxmlprs.h"
- // rmasmil
- #include "smlelem.h"
- #include "smlparse.h"
- #include "smltime.h"
- #include "smlprstime.h"
- // pndebug
- #include "debugout.h"
- #include "hxassert.h"
- #include "hxheap.h"
- #ifdef _DEBUG
- #undef HX_THIS_FILE
- static const char HX_THIS_FILE[] = __FILE__;
- #endif
- // /#define XXXEH_DEBUGOUT_ADDDURATION
- #if defined(XXXEH_DEBUGOUT_ADDDURATION)
- #define ADDDURATION_DEBUGOUT_STR_NEW_FILE "w"
- #define ADDDURATION_DEBUGOUT_STR_APPEND_TO_FILE "a+"
- static BOOL bFirstTimeAddDurDebugout = TRUE;
- #endif
- /*
- * CSmilTimelineElementManager methods
- */
- CSmilTimelineElementManager::CSmilTimelineElementManager():
- m_pElementMap(NULL),
- m_pNotifierMap(NULL)
- {
- }
- CSmilTimelineElementManager::~CSmilTimelineElementManager()
- {
- HX_DELETE(m_pElementMap);
- if(m_pNotifierMap)
- {
- CHXMapStringToOb::Iterator i = m_pNotifierMap->Begin();
- for(; i != m_pNotifierMap->End(); ++i)
- {
- CHXSimpleList* pList = (CHXSimpleList*)(*i);
- delete pList;
- }
- HX_DELETE(m_pNotifierMap);
- }
- }
- void
- CSmilTimelineElementManager::addTimelineElement(CSmilTimelineElement* pElement)
- {
- if(!m_pElementMap)
- {
- m_pElementMap = new CHXMapStringToOb;
- }
- (*m_pElementMap)[pElement->m_pID] = pElement;
- }
- CSmilTimelineElement*
- CSmilTimelineElementManager::getTimelineElement(const char* pID)
- {
- CSmilTimelineElement* pElement = NULL;
- if(m_pElementMap)
- {
- m_pElementMap->Lookup(pID, (void*&)pElement);
- }
- return pElement;
- }
- void
- CSmilTimelineElementManager::addNotification(const char* pID,
- CSmilTimelineElement* pElement)
- {
- if(!m_pNotifierMap)
- {
- m_pNotifierMap = new CHXMapStringToOb;
- }
- CHXSimpleList* pNotifyList = NULL;
- if(!m_pNotifierMap->Lookup(pID, (void*&)pNotifyList))
- {
- pNotifyList = new CHXSimpleList;
- (*m_pNotifierMap)[pID] = pNotifyList;
- }
- pNotifyList->AddTail(pElement);
- }
- void
- CSmilTimelineElementManager::notify(const char* pID)
- {
- CHXSimpleList* pNotifyList = NULL;
- if(m_pNotifierMap)
- {
- if(m_pNotifierMap->Lookup(pID, (void*&)pNotifyList))
- {
- CSmilTimelineElement* pDependentElement = NULL;
- if(m_pElementMap->Lookup(pID, (void*&)pDependentElement))
- {
- CHXSimpleList::Iterator i = pNotifyList->Begin();
- for(; i != pNotifyList->End(); ++i)
- {
- CSmilTimelineElement* pElement =
- (CSmilTimelineElement*)(*i);
- pElement->elementResolved(pDependentElement);
- }
- }
- }
- }
- }
- void
- CSmilTimelineElementManager::resetTimeline()
- {
- if(m_pElementMap)
- {
- CHXMapStringToOb::Iterator i = m_pElementMap->Begin();
- for(; i != m_pElementMap->End(); ++i)
- {
- CSmilTimelineElement* pElement =
- (CSmilTimelineElement*)(*i);
- pElement->reset();
- }
- }
- }
- /*
- * CSmilTimelineElement methods
- */
- CSmilTimelineElement::CSmilTimelineElement(CSmilElement* pSourceElement,
- CSmilParser* pParser):
- m_pSourceElement(pSourceElement),
- m_pParser(pParser),
- m_bDurationSet(FALSE),
- m_bMaxDurationSet(FALSE),
- m_bDelaySet(FALSE),
- m_bDontResetDuration(FALSE),
- m_bNonEventDelaySet(FALSE),
- m_ulNonEventDelay((UINT32)-1),
- m_bDelayEvent(FALSE),
- m_bDurationEvent(FALSE),
- m_pChildDurAddedMap(NULL),
- m_bHasChildWithScheduledBegin(FALSE),
- m_bInElementResolved(FALSE),
- m_pParent(NULL),
- m_pChildren(NULL),
- m_pDependent(NULL)
- {
- m_pID = new char[pSourceElement->m_pNode->m_id.GetLength() + 1];
- strcpy(m_pID, (const char*)m_pSourceElement->m_pNode->m_id); /* Flawfinder: ignore */
- //[SMIL 1.0 Compliance] Helps fix PR 26471:
- // /XXXEH- TODO: this is probably one of the places where
- // endsync="media" is handled. We probably don't want to do the
- // following if() statement if endsync is NOT media on the parent
- // of an anchor|area element:
- if (SMILAnchor != m_pSourceElement->m_pNode->m_tag &&
- SMILArea != m_pSourceElement->m_pNode->m_tag)
- {
- m_pParser->m_pTimelineElementManager->addTimelineElement(this);
- }
- if(pSourceElement->m_nBeginEventSourceTag == SMILEventSourceBegin ||
- pSourceElement->m_nBeginEventSourceTag == SMILEventSourceEnd ||
- pSourceElement->m_nBeginEventSourceTag == SMILEventSourceClock)
- {
- m_pParser->m_pTimelineElementManager->addNotification(pSourceElement->m_BeginEventSourceID,
- this);
- // /If we've already got a resolved begin, then we don't want to claim
- // that we're awaiting this sync-arc begin (as can happen if
- // begin="0s; x.begin+4s")
- if (!pSourceElement->m_bBeginOffsetSet)
- {
- m_bDelayEvent = TRUE;
- }
- }
- if(pSourceElement->m_nEndEventSourceTag == SMILEventSourceBegin ||
- pSourceElement->m_nEndEventSourceTag == SMILEventSourceEnd ||
- pSourceElement->m_nEndEventSourceTag == SMILEventSourceClock)
- {
- m_pParser->m_pTimelineElementManager->addNotification(pSourceElement->m_EndEventSourceID,
- this);
- // /If we've already got a resolved end, then we don't want to claim
- // that we're awaiting this sync-arc end (as can happen if
- // end="10s; x.begin+14s")
- if (!pSourceElement->m_bEndOffsetSet)
- {
- m_bDurationEvent = TRUE;
- }
- }
- if(pSourceElement->m_nEndsyncEventSourceTag == SMILEventSourceID)
- {
- m_pParser->m_pTimelineElementManager->addNotification(pSourceElement->m_EndsyncEventSourceID,
- this);
- m_bDurationEvent = TRUE;
- }
- m_pChildDurAddedMap = new CHXMapStringToOb();
- // /XXXEH- TODO: make sure this is what we want to do:
- // /Get next resolved time, if any. If none are found in a non-empty
- // begin-time list, then treat this as a delayed event:
- if (NULL != pSourceElement->m_pBeginTimeList &&
- !pSourceElement->m_pBeginTimeList->IsEmpty())
- {
- SmilTimeValue* pNextResolvedTimeValue = NULL;
- HX_RESULT rettimeval = HXR_OK;
- rettimeval = pSourceElement->getNextResolvedTimeValue(
- pNextResolvedTimeValue,
- // /XXXEH- TODO: make sure we don't want to input cur time here;
- // is it possible that we'd get here after time 0 in the parent
- // timeline??? I don't think so...:
- SMILTIME_NEGATIVE_INFINITY,
- SMILTIME_NEGATIVE_INFINITY,
- SmilBeginTimeList,
- /* Don't need list of resolved times:*/ NULL);
- if (!SUCCEEDED(rettimeval) || NULL == pNextResolvedTimeValue)
- {
- // /Has no resolved time yet so must be awaiting an event:
- m_bDelayEvent = TRUE;
- }
- }
- }
- CSmilTimelineElement::~CSmilTimelineElement()
- {
- delete m_pChildren;
- delete[] m_pID;
- HX_DELETE(m_pChildDurAddedMap);
- }
- void
- CSmilTimelineElement::reset()
- {
- m_bDelaySet = FALSE;
- m_bNonEventDelaySet = FALSE;
- m_ulNonEventDelay = (UINT32)-1;
- m_bDurationSet = FALSE;
- m_bMaxDurationSet = FALSE;
- // /XXXEH- do we really want to do this? Find a way to test this:
- #if defined(XXXEH_NEEDS_TESTING)
- HX_DELETE(m_pChildDurAddedMap); // /start fresh
- #endif
- }
- void
- CSmilTimelineElement::prepForRestart()
- {
- m_bDelaySet = FALSE;
- m_bNonEventDelaySet = FALSE;
- m_ulNonEventDelay = (UINT32)-1;
- #if XXXEH_OLD_WAY_THAT_DIDNT_LET_SETDURATION_TAKE_CARE_OF_NEW_DUR
- if (((UINT32)-1) != m_pSourceElement->m_ulOriginalDuration)
- {
- resetDuration(m_pSourceElement->m_ulOriginalDuration);
- }
- // /Note: leave m_bDurationSet & m_bMaxDurationSet alone for restart
- #else
- //...But if we're restarting, our duration may be different and this
- // gets handled in CSmilTimelineElement::setDuration():
- m_bDurationSet = FALSE;
- // /Fixes PR 54704: if we don't reset this in concert with resetting
- // m_bDurationSet, above, then ancestorEventsAreResolved() will fail
- // when a re-insertTimelineElement() call on this occurs:
- m_bDurationEvent = FALSE;
- #endif
- }
- void
- CSmilTimelineElement::setDelay(UINT32 ulDelay, BOOL bSetByParent)
- {
- ULONG32 ulPreviouslySetDelay = m_pSourceElement->m_ulDelay;
- ULONG32 ulPreviouslySetPureDuration = m_pSourceElement->getPureDuration();
- #if defined(_DEBUG) && defined(XXXEH_DEBUGOUT_ADDDURATION)
- {
- FILE* f1 = ::fopen("c:\smil2AddDuration.txt", bFirstTimeAddDurDebugout?
- ADDDURATION_DEBUGOUT_STR_NEW_FILE :
- ADDDURATION_DEBUGOUT_STR_APPEND_TO_FILE );
- ::fprintf(f1, "CSmilTimelineElement{%s}::setDelay(delay=%lu, "
- "bSetByParent=%sE), prior delay=%lu, m_bDelaySet=%sEn",
- (const char*)m_pID, ulDelay,
- bSetByParent?"TRU":"FALS",
- ulPreviouslySetDelay,
- m_bDelaySet?"TRU":"FALS");
- ::fclose(f1);
- bFirstTimeAddDurDebugout = FALSE;
- }
- #endif
- if(!m_bDelaySet)
- {
- // /For PR 59584: if we're just resolving this to let the
- // group duration "resolve" to unresolved, don't count begin:
- if(WAY_IN_THE_FUTURE <= ulDelay)
- {
- HX_ASSERT(WAY_IN_THE_FUTURE >= ulDelay);
- }
- else if(!m_bDelayEvent)
- {
- BOOL bDelayClippedDueToNegOffset = FALSE;
- if(m_pSourceElement->m_bBeginOffsetSet)
- {
- m_pSourceElement->m_ulDelay = ulDelay;
- // /Handle all cases so that we don't overflow:
- UINT32 ulPosOffset = m_pSourceElement->m_lBeginOffset > 0?
- m_pSourceElement->m_lBeginOffset : 0;
- UINT32 ulNegOffset = m_pSourceElement->m_lBeginOffset < 0?
- (UINT32)(-m_pSourceElement->m_lBeginOffset) : 0;
- UINT32 ulClippedAmt = 0;
- if (ulNegOffset > 0)
- {
- m_pSourceElement->m_bNegBeginOffsetAlreadyUsed =
- TRUE;
- }
- m_pSourceElement->m_ulDelay += ulPosOffset;
- if (m_pSourceElement->m_ulDelay >= ulNegOffset)
- {
- m_pSourceElement->m_ulDelay -= ulNegOffset;
- }
- else
- {
- // /If set by parent, then we want to use the entire
- // negative offset FROM OUR PARENT's BEGIN which already
- // has the delay in it, so <par begin="2s"><ref begin=
- // "-3s" ...> would begin the ref at 2s w/3s clip-begin:
- ulClippedAmt = bSetByParent? ulNegOffset : ulNegOffset -
- m_pSourceElement->m_ulDelay;
- // /If clip-begin is invalid, set it otherwise add to it:
- m_pSourceElement->m_ulClipBegin = ((UINT32)-1 ==
- m_pSourceElement->m_ulAuthoredClipBegin?
- ulClippedAmt : ulClippedAmt +
- m_pSourceElement->m_ulAuthoredClipBegin);
- if ((UINT32)-1 != m_pSourceElement->m_ulDuration)
- {
- if (m_pSourceElement->m_ulDuration > ulClippedAmt)
- {
- m_pSourceElement->m_ulDuration -= ulClippedAmt;
- }
- // /else duration is negative; it can't ever play.
- else
- {
- m_pSourceElement->m_ulDuration = 0;
- }
- }
- }
- }
- // /Fixes most of PR64499: when restarting the parent of a
- // long-sync-arc-begun element, the begin should still be based on
- // the long sync-arc's global time:
- else if ((UINT32)-1 != m_pSourceElement->m_ulLongSyncArcBeginInGroupTime
- && m_pSourceElement->m_bIsRestarting)
- {
- SMILNode* pSyncNode = !m_pParser? NULL :
- m_pParser->getSyncAncestor(m_pSourceElement->m_pNode);
- HX_ASSERT(pSyncNode && pSyncNode->m_pElement);
- if (pSyncNode && pSyncNode->m_pElement->m_bIsRestarting)
- {
- m_pSourceElement->m_ulDelay =
- m_pSourceElement->m_ulLongSyncArcBeginInGroupTime;
- }
- }
- // /Else we've established that the beginOffset is not set, so
- // just use the delay:
- else
- {
- m_pSourceElement->m_ulDelay = ulDelay;
- // /Fixes PR 71386 and PR 77406: event-based begins with sync-
- // arc ends (that are already resolved, here) should not
- // include the delay twice; use the *end* not the *duration*:
- if (m_pSourceElement->m_bEndOffsetSet &&
- // /Fixes PR 8XYXZ (broken by original PR 71386 fix);
- // If being set by parent, we don't need to do anything
- // because delay is parent delay, not explicitly-set
- // begin val:
- !bSetByParent)
- {
- // /If dur was explicitly authored along with end, use the
- // min(end, dur+delay):
- if (WAY_IN_THE_FUTURE ==
- m_pSourceElement->m_ulAuthoredDur ||
- (UINT32)-1 == m_pSourceElement->m_ulAuthoredDur ||
- // /Fixes PR 71386 Part 3 = version where element
- // has end="x.end" AND has dur="z"; if z+delay >
- // x.end, ignore dur:
- (m_pSourceElement->m_ulAuthoredDur +
- m_pSourceElement->m_ulDelay >
- m_pSourceElement->m_lEndOffset))
- {
- if (m_pSourceElement->m_lEndOffset > 0 &&
- (ULONG32)m_pSourceElement->m_lEndOffset >=
- m_pSourceElement->m_ulDelay)
- {
- m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase =
- FALSE;
- m_pSourceElement->m_ulDuration =
- m_pSourceElement->m_lEndOffset -
- m_pSourceElement->m_ulDelay;
- }
- else
- {
- HX_ASSERT(0 && "pleaseContact_ehodge!");
- m_pSourceElement->m_ulDuration = 0;
- }
- }
- }
- }
- m_bDelaySet = TRUE;
- if (HXR_OK == m_pParser->adjustForNegativeOffset(m_pID))
- {
- m_pParser->insertTimelineElement(m_pID,
- m_pSourceElement->m_ulDelay);
- }
- // XXXMEH - animation can be children of media elements, so when
- // a media element gets its delay set, then we need to
- // set the delay of any children
- if(m_pChildren)
- {
- LISTPOSITION pos = m_pChildren->GetHeadPosition();
- while (pos)
- {
- CSmilTimelineElement* pChildElement =
- (CSmilTimelineElement*) m_pChildren->GetNext(pos);
- if (pChildElement)
- {
- pChildElement->setDelay(m_pSourceElement->m_ulDelay, TRUE);
- }
- }
- }
- }
- }
- else
- {
- HX_ASSERT(WAY_IN_THE_FUTURE > ulDelay); // /PR 59584-related check.
- if(m_pSourceElement->m_bBeginOffsetSet)
- {
- m_pSourceElement->m_ulDelay = (
- ((INT32)ulDelay+m_pSourceElement->m_lBeginOffset > 0) ?
- (UINT32)((INT32)ulDelay+m_pSourceElement->m_lBeginOffset):0);
- }
- else
- {
- // /There are two cases where we might arrive here with
- // ulDelay not equalling ulPreviouslySetDelay; one is when the
- // original delay is based on a sync-arc to an element that never
- // gets added to the timeline, and the other is when the original
- // delay is based on a long sync-arc. The following allows both
- // to work; we don't want to use the new delay if the orig one
- // was greater than the new one, otherwise we'll play it too soon
- // and that happens in SMIL2 Timing interop case 1.15:
- if (!bSetByParent || ulDelay > ulPreviouslySetDelay)
- {
- m_pSourceElement->m_ulDelay = ulDelay;
- }
- }
- // /If we've got a long sync-arc begin delay that is earlier (and
- // also resolved earlier) than our parent's begin delay, then we want
- // to do a clip-begin of the difference, e.g,:
- // <par begin="3s">
- // <video begin="someElementBeginningAtTimeZero.begin" .../> ...
- // so the video element should begin at 3s and clip the 1st 3s of it.
- if (bSetByParent &&
- ulPreviouslySetDelay < m_pSourceElement->m_ulDelay)
- {
- LONG32 lDiff = m_pSourceElement->m_ulDelay -ulPreviouslySetDelay;
- HX_ASSERT(lDiff >= 0);
- ULONG32 ulDiff = (ULONG32)lDiff;
- // /If clip-begin is invalid, set it otherwise add to it:
- m_pSourceElement->m_ulClipBegin = ((UINT32)-1 ==
- m_pSourceElement->m_ulAuthoredClipBegin?
- ulDiff : ulDiff+m_pSourceElement->m_ulAuthoredClipBegin);
- if ((UINT32)-1 != m_pSourceElement->m_ulDuration)
- {
- if (m_pSourceElement->m_ulDuration > ulDiff)
- {
- m_pSourceElement->m_ulDuration -= ulDiff;
- }
- else
- {
- m_pSourceElement->m_ulDuration = 0;
- }
- if (m_pSourceElement->m_pNode)
- {
- m_pParser->resetTimelineElementDuration(
- (const char*)m_pSourceElement->m_pNode->m_id,
- m_pSourceElement->getPureDuration(),
- ulPreviouslySetPureDuration);
- m_pParser->m_pTimelineElementManager->notify(
- (const char*)m_pSourceElement->m_pNode->m_id);
- }
- }
- }
- // /More for PR 50411: if it wasn't inserted yet, do so:
- // /(Also helps fix other long-sync-arc bugs like PR 64498 & PR 64499):
- if (m_pSourceElement->m_bAwaitingSyncAncestorBeginNotification)
- {
- HX_ASSERT(!m_pSourceElement->m_bInsertedIntoTimeline);
- m_pParser->insertTimelineElement(m_pID,
- m_pSourceElement->m_ulDelay);
- m_pSourceElement->m_bAwaitingSyncAncestorBeginNotification =
- FALSE;
- }
- }
- // /This helps fix PR 50588 (and other sync-arc-to-x's-begin-where-x-has-
- // resolved-delay-but-not-resolved-duration bugs); notify sync-arc
- // dependents if our delay (or duration) was set or changed:
- if (ulPreviouslySetDelay != m_pSourceElement->m_ulDelay ||
- ulPreviouslySetPureDuration != m_pSourceElement->getPureDuration())
- {
- m_pParser->m_pTimelineElementManager->notify(m_pID);
- }
- }
- void
- CSmilTimelineElement::setDuration(UINT32 ulDuration, BOOL bSetFromParent,
- BOOL bDurationExtendingDueToPause)
- {
- #if defined(_DEBUG) && defined(XXXEH_DEBUGOUT_ADDDURATION)
- {
- FILE* f1 = ::fopen("c:\smil2AddDuration.txt", bFirstTimeAddDurDebugout?
- ADDDURATION_DEBUGOUT_STR_NEW_FILE :
- ADDDURATION_DEBUGOUT_STR_APPEND_TO_FILE );
- ::fprintf(f1, "CSmilTimelineElement{%s}::setDuration(ulDuration=%lu, "
- "bSetFromParent=%sE) m_pSourceElement->m_ulDelay=%lu, m_bDelaySet=%sn",
- (const char*)m_pID, ulDuration,
- bSetFromParent?"TRU":"FALS", m_pSourceElement->m_ulDelay,
- m_bDelaySet?"TRUE":"FALSE-#############!!! DUDE!");
- ::fclose(f1);
- bFirstTimeAddDurDebugout = FALSE;
- }
- #endif
- BOOL bTrackStartsTooLateSoTrackRemoved = FALSE;
- ULONG32 ulPriorPureDuration = m_pSourceElement->getPureDuration();
- if(bSetFromParent)
- {
- BOOL bOKToOverrideDuration = FALSE;
- if ((UINT32)-1 == m_pSourceElement->m_ulAuthoredDur)
- {
- if (!m_pSourceElement->m_bHasExplicitEnd || !m_bDurationSet)
- {
- bOKToOverrideDuration = TRUE;
- }
- }
- else if (m_pSourceElement->m_ulAuthoredDur == WAY_IN_THE_FUTURE &&
- m_pSourceElement->m_bHasExplicitEnd && m_bDurationSet &&
- // /Fixes PR 50676 part 5: if m_bDurationSet but duration was
- // not set to anything but unresolved, then we do want to
- // override the unresolved value; this continues to let the
- // fix work from 5/9/2001's addition of this else-if:
- m_pSourceElement->m_ulDuration != WAY_IN_THE_FUTURE)
- {
- bOKToOverrideDuration = FALSE;
- }
- else if (m_pSourceElement->m_ulAuthoredDur >= ulDuration &&
- ((UINT32)-1 == m_pSourceElement->m_ulMaxActiveDur ||
- m_pSourceElement->m_ulMaxActiveDur >= ulDuration) )
- {
- // /XXXEH- I need to find content that has this feature;
- // I'm pretty sure I want to add m_ulBeginOffsetFromSyncBase to
- // m_ulAuthoredDur when comparing with ulDuration, above, since
- // ulDuration is in syncbase time coordinate system:
- HX_ASSERT((!m_pSourceElement->m_bCurBeginIsOffsetFromSyncBase ||
- (m_pSourceElement->m_ulBeginOffsetFromSyncBase +
- m_pSourceElement->m_ulAuthoredDur >= ulDuration) ) &&
- "contact ehodge to fix");
- bOKToOverrideDuration = TRUE;
- }
- // /If begin="5s" and end|dur|max are explicitly set, don't override
- // the duration (interop #1.1: BeginEndEvents_Case1.smi):
- // /XXXEH- make sure delay is accounted for (if "ulDuration" is
- // really delay+dur):
- if (bOKToOverrideDuration)
- {
- // /Fixes BUG-20001116_parDurExtended_due_to_syncArc_delay.smi:
- ULONG32 ulRevisedDur = ulDuration;
- BOOL bOkToSetDuration = TRUE;
- BOOL bOKToResetDurationIncludesDelayVar = TRUE;
- BOOL bRevisedDurDoesNotIncludeDelayBeyondSyncbase = FALSE;
- // /Note: when we say "parent" in this function, we really
- // mean sync ancestor (e.g., par when switch is our parent and
- // par is parent of switch).
- ULONG32 ulSyncBaseDelay = (UINT32)-1;
- SMILNode* pSyncNode = !m_pParser? NULL :
- m_pParser->getSyncAncestor(m_pSourceElement->m_pNode);
- HX_ASSERT(pSyncNode && pSyncNode->m_pElement);
- if (pSyncNode && pSyncNode->m_pElement)
- {
- ulSyncBaseDelay = pSyncNode->m_pElement->m_ulDelay;
- // /XXXEH- in PR 59584 (which works OK with code as-is),
- // syncNode is a Seq but prior sibling should really be
- // treated as the "sync base", not the seq. There are 3
- // other places in this file where this code is needed,
- // but need content that's broken by this before I fix it: PR 6XXX5:
- if (pSyncNode->m_tag == SMILSeq)
- {
- ulSyncBaseDelay = m_pParser->
- getSyncBaseTimeInGroupTimeCoords(
- m_pSourceElement->m_pNode);
- }
- }
- // /We need to make sure that our begin+duration does not exceed
- // our parent's end; the ulDuration begin passed in is our
- // syncBase-imposed duration that already includes our syncBase's
- // delay but does not take into account our begin offset or
- // delay relative to our syncBase's begin. To adjust for this,
- // set the new duration to ulDuration minus (beginOffset set?
- // beginOffset : (delay-parentDelay): Note that we can have a
- // delay that is due to a sync-arc and not due to our syncBase's
- // delay and thus we may not have a beginOffset set but we still
- // may begin later than our syncBase:
- if (m_pSourceElement->m_bBeginOffsetSet)
- {
- // /Include this code because it fixes
- // <par dur="5s" begin="1s"><ref begin="2s"/></par>
- // as in BUG-20001116_parDurExtended_due_to_syncArc_delay.smi
- // (which broke again due to fix for PR 53514, below, I think):
- if (m_pSourceElement->m_lBeginOffset > 0)
- {
- ulRevisedDur=((ULONG32)m_pSourceElement->m_lBeginOffset>=
- ulRevisedDur)? 0 : (ulRevisedDur -
- (ULONG32)m_pSourceElement->m_lBeginOffset);
- bRevisedDurDoesNotIncludeDelayBeyondSyncbase = TRUE;
- // /Fixes PR 58568: if revised dur is 0 or negative
- // (ULONG32 floor of 0 prevents it from being negative),
- // then we need to remove the track if it's been added
- // already, otherwise it'll play in spite of it's
- // parent ending before that time:
- if (0 == ulRevisedDur)
- {
- if (m_pSourceElement->m_pHandler &&
- m_pSourceElement->m_bInsertedIntoTimeline)
- {
- // /The following signals subsequent timeline
- // adjustments to ignore this element in parent
- // duration computations:
- m_pSourceElement->m_bCurEndClippedByParent = TRUE;
- HX_RESULT retval2 = m_pSourceElement->m_pHandler->
- handleTrackRemoval((const char*)m_pID,
- (INT32)m_pSourceElement->m_pNode->m_nGroup);
- if (HXR_OK == retval2)
- {
- // /XXXEH- verify in SMIL 2.0 spec how to
- // handle syncArcs to element that's beyond
- // its syncBase and thus won't start:
- // /Fixes case where element has sync arc
- // to this end time and we need to notify it
- // that we've ended early:
- m_pParser->m_pTimelineElementManager->notify((const char*)m_pID);
- bTrackStartsTooLateSoTrackRemoved = TRUE;
- goto cleanup;
- }
- }
-
- }
- }
- }
- else // /No begin offset, so use delay minus syncBase delay:
- {
- if (pSyncNode && pSyncNode->m_pElement)
- {
- if ((UINT32)-1 != ulSyncBaseDelay &&
- (UINT32)-1 != m_pSourceElement->m_ulDelay )
- {
- HX_ASSERT(m_pSourceElement->m_ulDelay >=
- ulSyncBaseDelay);
- if (m_pSourceElement->m_ulDelay > ulSyncBaseDelay ||
- // /Helps fix PR 66391: if delays are equal &
- // revisedDur=0, then remove this track:
- (0 == ulRevisedDur &&
- m_pSourceElement->m_ulDelay == ulSyncBaseDelay))
- {
- ULONG32 ulEffectiveBeginOffset =
- m_pSourceElement->m_ulDelay -
- ulSyncBaseDelay;
- ulRevisedDur =
- ulRevisedDur>ulEffectiveBeginOffset?
- ulRevisedDur-ulEffectiveBeginOffset : 0;
- bRevisedDurDoesNotIncludeDelayBeyondSyncbase = TRUE;
- bOKToResetDurationIncludesDelayVar = FALSE;
- // /Be sure to update the begin offset relative
- // to the parent: Helps fix
- // "...20001116_parDurExtended_due_to_syncArc..."
- m_pSourceElement->m_bCurBeginIsOffsetFromSyncBase =
- TRUE;
- m_pSourceElement->m_ulBeginOffsetFromSyncBase =
- ulEffectiveBeginOffset;
- // /Fixes part of PR 50684: if revised dur is 0
- // or negative (ULONG32 floor of 0 prevents it
- // from being negative), then we need to remove
- // the track if it's been added already:
- if (0 == ulRevisedDur &&
- m_pSourceElement->m_pHandler &&
- m_pSourceElement->m_bInsertedIntoTimeline)
- {
- m_pSourceElement->m_bCurEndClippedByParent = TRUE;
- HX_RESULT retval2 = m_pSourceElement->m_pHandler->
- handleTrackRemoval((const char*)m_pID,
- (INT32)m_pSourceElement->m_pNode->m_nGroup);
- if (HXR_OK == retval2)
- {
- // /Fixes case where element has sync arc
- // to this end time and we need to notify it
- // that we've ended early:
- m_pParser->m_pTimelineElementManager->notify((const char*)m_pID);
- bTrackStartsTooLateSoTrackRemoved = TRUE;
- goto cleanup;
- }
- }
- }
-
- }
- else if ((UINT32)-1 == ulSyncBaseDelay)
- {
- // /Fixes case where par parent child of excl was
- // allowing child to begin even though par has no
- // explicit resolved begin and thus shouldn't begin:
- bOkToSetDuration = FALSE;
- }
- }
- }
- if (bOkToSetDuration && ((UINT32)-1 ==
- m_pSourceElement->m_ulDuration ||
- m_pSourceElement->m_ulDuration < ulRevisedDur) )
- {
- HX_ASSERT(m_pSourceElement->m_ulDuration == m_pSourceElement->getPureDuration());
- // /Adding this if() fixes PR 53514; parent explicit dur was
- // being forced on this child even if child has a shorter
- // intrinsic duration (which isn't known yet). We need to
- // hold off setting the duration and rather set the max
- // duration:
- setMaxDuration(ulRevisedDur);
- }
- else if (bOkToSetDuration)
- {
- m_bDurationSet = m_bDontResetDuration = TRUE;
- if (m_pSourceElement->m_ulDuration != ulRevisedDur)
- {
- // /Parent-imposed duration always is relative to parent
- // begin, so duration thus includes delay offset from
- // parent. Don't set flag unless offset>0, for
- // consistency:
- if (m_pSourceElement->m_bCurBeginIsOffsetFromSyncBase &&
- m_pSourceElement->m_ulBeginOffsetFromSyncBase > 0)
- {
- m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase = TRUE;
- }
- if (bRevisedDurDoesNotIncludeDelayBeyondSyncbase)
- {
- m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase = FALSE;
- }
- // /Adding this if() conditional around the call to
- // "resetTimelineElement...()" makes PR55885 happen only
- // after the first time it's played. If you don't close
- // the player and then restart the clip, sometimes 55885
- // bug still appears; need to debug with core folks to
- // see why this happens.
- // /NOTE: Adding the following conditional *does* 100% fix
- // "BUG-20010613-clickAllFourAndRestartOfGreenCauses..."
- // "...ExtensionOfTimelinePastParEnd.smil":
- if ((UINT32)-1 != m_pSourceElement->m_ulDelay)
- {
- m_pParser->resetTimelineElementDuration(m_pID,
- // /Using the revised dur here helps fix
- // PR 59223, PR 50684, & PR 56795 (and
- // probably a lot of others):
- ulRevisedDur, ulPriorPureDuration);
- }
- }
- }
- }
- // /Fixes bug where par with a synchbase end (e.g., end="foo.begin")
- // was being ignored completely because its children were never
- // being added to the timeline:
- if (!m_pSourceElement->m_bInsertedIntoTimeline)
- {
- if (HXR_OK == m_pParser->adjustForNegativeOffset(m_pID))
- {
- // /Helps fix timing interop cases in the 11.2-11.9 range:
- if ((UINT32)-1 != m_pSourceElement->m_ulDelay)
- {
- m_pParser->insertTimelineElement(m_pID,
- m_pSourceElement->m_ulDelay);
- }
- }
- }
- }
- else // /Else this duration is not being set by parent:
- {
- if(!m_bDurationSet ||
- // /Helps fix PR 86107; if pause is extending duration, we're
- // only here to notify our dependents and ancestor excl so it
- // can potentially update its duration so subSEQuent clips can
- // adjust their delays outward before getting scheduled w/core:
- bDurationExtendingDueToPause)
- {
- LONG32 lDelayFromParentBegin = 0;
- HX_ASSERT((!m_pSourceElement->m_bBeginOffsetSet ||
- m_pSourceElement->m_lBeginOffset>=0 ||
- m_pSourceElement->m_bNegBeginOffsetAlreadyUsed) &&
- "ehodge_please_help_me_find_content_that_trips_this");
- if (m_pSourceElement->m_bBeginOffsetSet &&
- // /Don't adjust if already adjusted for neg offset:
- !m_pSourceElement->m_bNegBeginOffsetAlreadyUsed)
- {
- lDelayFromParentBegin = m_pSourceElement->m_lBeginOffset;
- }
- // /Handle case where element began based on event or late-
- // resolving time, in which case we want to treat the diff
- // between when it resolved and what its sync-parent begin
- // is as if it were a m_lBeginOffset:
- else if (m_pSourceElement->m_bCurBeginIsOffsetFromSyncBase)
- {
- lDelayFromParentBegin = (LONG32)
- m_pSourceElement->m_ulBeginOffsetFromSyncBase;
- }
- if (lDelayFromParentBegin>0 &&
- // /1st part of fix for interop case 1.15 where begin and
- // end are explicitly set to same val so dur should be 0:
- ulDuration != 0)
- {
- m_pSourceElement->m_ulDuration = (
- ((INT32)ulDuration + lDelayFromParentBegin >0) ?
- (UINT32)(
- (INT32)ulDuration + lDelayFromParentBegin) : 0);
- // /NOTE: m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase
- // is TRUE in PR 79699 (occasionally) but it plays as expected so
- // I removed the HX_ASSERT() on !(..->m_bDurationIncludesDelay...)].
- // /XXXEH- 20020625: maybe don't do above adding of delay, and then set this to FALSE?:
- m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase = TRUE;
- // /If duration is unresolved or indefinite, don't include
- // delay from parent so parent duration doesn't get extended
- // beyond WAY_IN_THE_FUTURE:
- if (WAY_IN_THE_FUTURE == ulDuration)
- {
- m_pSourceElement->m_ulDuration = WAY_IN_THE_FUTURE;
- }
- }
- else
- {
- lDelayFromParentBegin = 0; // /In case it was negative.
- m_pSourceElement->m_ulDuration = ulDuration;
- // /If end==begin, we need to NOT play the clip but we do
- // need to fire a beginEvent and endEvent for it. However,
- // if end < begin, we don't fire these events (as in
- // SMIL 2.0 Interop Timing case 1.16):
- BOOL bEndBeforeBegin =
- m_pSourceElement->m_bBeginOffsetSet &&
- m_pSourceElement->m_bEndOffsetSet &&
- m_pSourceElement->m_lBeginOffset >
- m_pSourceElement->m_lEndOffset;
- if (0 == m_pSourceElement->m_ulDuration &&
- !bEndBeforeBegin && m_pSourceElement->m_pNode)
- {
- // /Raise a beginEvent but don't play the thing (as in
- // SMIL 2.0 Interop Timing case 1.15):
- HX_RESULT rslt = HXR_OK;
- rslt = m_pParser->tryToResolveBeginEndEvents(
- "beginEvent",
- (const char*)m_pSourceElement->m_pNode->m_id,
- m_pSourceElement->m_ulDelay);
- rslt = m_pParser->tryToResolveBeginEndEvents(
- "endEvent",
- (const char*)m_pSourceElement->m_pNode->m_id,
- m_pSourceElement->m_ulDelay);
- }
- }
- m_bDurationSet = TRUE;
- HX_ASSERT(m_pSourceElement->m_ulDuration>0 &&
- "timing#1.15: child's dur (=0) not added to parent; refix!");
- if(m_pParent &&
- // /Timing interop case 1.15 2nd part of fix:
- m_pSourceElement->m_ulDuration>0)
- {
- m_pParent->addDuration(m_pSourceElement->m_ulDuration,
- m_pSourceElement->m_ulDelay,
- (UINT32)lDelayFromParentBegin, m_pID);
- m_pSourceElement->m_bAddDurationAlreadyDone = TRUE;
- }
- // /Only do this if we're really setting the original duration
- // (and not updating duration due to predicted pause extension):
- if (!bDurationExtendingDueToPause)
- {
- // /this keeps track of dur="x" or implicit source dur, in
- // case this element restarts after playing at least once:
- m_pSourceElement->m_ulOriginalDuration =
- m_pSourceElement->getPureDuration();
- HX_ASSERT(ulDuration == m_pSourceElement->getPureDuration() ||
- m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase);
- }
- }
- else if(!m_bDontResetDuration)
- {
- m_pSourceElement->m_ulDuration = ulDuration;
- m_pParser->resetTimelineElementDuration(m_pID,
- m_pSourceElement->getPureDuration(),
- ulPriorPureDuration);
- // /this keeps track of dur="x" or implicit source dur, in
- // case this element restarts after playing at least once:
- m_pSourceElement->m_ulOriginalDuration =
- m_pSourceElement->getPureDuration();
- HX_ASSERT(ulDuration == m_pSourceElement->getPureDuration() ||
- m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase);
- }
- // /Adding the following else-if fixes PR 52110: if parent explicit
- // dur sets this's duration but this never got added to parent (via
- // addDuration()), then all subSEQuent tracks won't ever get resolved
- // begins:
- else if(!m_pSourceElement->m_bAddDurationAlreadyDone)
- {
- HX_ASSERT(m_bDurationSet); // /Here because this was already set.
- HX_ASSERT(m_bDelaySet && (UINT32)-1 != m_pSourceElement->m_ulDelay);
- HX_ASSERT(m_pSourceElement->m_ulDuration>0 &&
- "child's dur (=0) not added to parent; refix!");
- if(m_pParent && m_pSourceElement->m_ulDuration>0)
- {
- ULONG32 ulDelayFromSyncBaseBegin = 0;
- if (m_pSourceElement->m_bCurBeginIsOffsetFromSyncBase)
- {
- ulDelayFromSyncBaseBegin =
- m_pSourceElement->m_ulBeginOffsetFromSyncBase;
- }
- m_pParent->addDuration(m_pSourceElement->m_ulDuration,
- m_pSourceElement->m_ulDelay,
- ulDelayFromSyncBaseBegin, m_pID);
- m_pSourceElement->m_bAddDurationAlreadyDone = TRUE;
- }
- }
- // /If "dur" attribute value or intrinsic dur is less than the
- // min attribute value or greater than the max attribute value,
- // then we need to use min or max attribute's value as the duration:
- if (!m_bDontResetDuration &&
- (m_pSourceElement->m_bUseMediaDurForMinDur ||
- m_pSourceElement->m_bUseMediaDurForMaxDur ||
- m_pSourceElement->m_ulMinActiveDur > 0 ||
- m_pSourceElement->m_ulMaxActiveDur != ((UINT32)-1) ) )
- {
- BOOL bDoUpdate = FALSE;
- LONG32 lBeginOffset = 0;
- if (m_pSourceElement->m_bBeginOffsetSet)
- {
- lBeginOffset = m_pSourceElement->m_lBeginOffset;
- }
- // /First, check if m_pSourceElement->m_bUseMediaDurForMinDur
- // is TRUE. If so, we want to use the max of ulDuration
- // (media's intrinsic dur) and any explicitly-set dur (via
- // dur="..." {or end="..."[-begin=".."]}:
- if (m_pSourceElement->m_bUseMediaDurForMinDur)
- {
- if (((UINT32)-1) != m_pSourceElement->m_ulAuthoredDur)
- {
- HX_ASSERT(0 == m_pSourceElement->m_ulMinActiveDur);
- // /Use authored dur if it's greater than intrinsic
- // duration OR if max<min (since max<min negates both
- // properties):
- if (m_pSourceElement->m_ulAuthoredDur > ulDuration ||
- (((UINT32)-1) !=
- m_pSourceElement->m_ulMaxActiveDur &&
- m_pSourceElement->m_ulMaxActiveDur < ulDuration))
- {
- m_pSourceElement->m_ulDuration =
- m_pSourceElement->m_ulAuthoredDur;
- bDoUpdate = TRUE;
- }
- }
- }
- // /Next, check if m_pSourceElement->m_bUseMediaDurForMaxDur
- // is TRUE. If so, we want to use the min of ulDuration
- // (media's intrinsic dur) and any explicitly-set dur (via
- // dur="..." or {end="..."[-begin=".."]}:
- else if (m_pSourceElement->m_bUseMediaDurForMaxDur)
- {
- if (((UINT32)-1) != m_pSourceElement->m_ulAuthoredDur)
- {
- HX_ASSERT(((UINT32)-1) ==
- m_pSourceElement->m_ulMaxActiveDur);
- // /Use authored dur if it's less than intrinsic
- // duration OR if min>max (since min>max negates both
- // properties):
- if (m_pSourceElement->m_ulAuthoredDur < ulDuration ||
- (0 != m_pSourceElement->m_ulMinActiveDur &&
- m_pSourceElement->m_ulMinActiveDur > ulDuration))
- {
- m_pSourceElement->m_ulDuration =
- m_pSourceElement->m_ulAuthoredDur;
- bDoUpdate = TRUE;
- }
- }
- }
- // /If no "dur" or "end" was specified, use the greater of the
- // media's intrinsic dur and its min without exceeding its max,
- // if any:
- else if(((UINT32)-1) == m_pSourceElement->m_ulAuthoredDur)
- {
- if (m_pSourceElement->m_ulMinActiveDur!=0 &&
- m_pSourceElement->m_ulDuration <
- m_pSourceElement->m_ulMinActiveDur)
- {
- m_pSourceElement->m_ulDuration =
- m_pSourceElement->m_ulMinActiveDur;
- bDoUpdate = TRUE;
- }
- if (((UINT32)-1) != m_pSourceElement->m_ulMaxActiveDur &&
- m_pSourceElement->m_ulDuration >
- m_pSourceElement->m_ulMaxActiveDur)
- {
- m_pSourceElement->m_ulDuration =
- m_pSourceElement->m_ulMaxActiveDur;
- bDoUpdate = TRUE;
- }
- }
- // /If the duration is less than the specified min, use
- // the min (and we already know that the min < max, so we don't
- // need to look at the max, if any):
- else if (m_pSourceElement->m_ulDuration <
- m_pSourceElement->m_ulMinActiveDur)
- {
- m_pSourceElement->m_ulDuration =
- m_pSourceElement->m_ulMinActiveDur;
- bDoUpdate = TRUE;
- }
- // /If the duration authored is greater than the specified max,
- // use the max (and we already know that the min < max, so we
- // don't need to look at the min, if any):
- else if (m_pSourceElement->m_ulDuration >
- m_pSourceElement->m_ulMaxActiveDur)
- {
- m_pSourceElement->m_ulDuration =
- m_pSourceElement->m_ulMaxActiveDur;
- bDoUpdate = TRUE;
- }
- else // /use authored duration:
- {
- m_pSourceElement->m_ulDuration =
- m_pSourceElement->m_ulAuthoredDur;
- bDoUpdate = TRUE;
- }
- if (bDoUpdate)
- {
- LONG32 lDiff =
- (LONG32)m_pSourceElement->m_ulDuration +
- lBeginOffset;
- m_pSourceElement->m_ulDuration = lDiff>0?
- lDiff : 0;
- m_pParser->resetTimelineElementDuration(m_pID,
- m_pSourceElement->getPureDuration(),
- ulPriorPureDuration);
- // /This keeps track of first-play dur, in case this
- // element restarts during or after playing at least
- // once:
- m_pSourceElement->m_ulOriginalDuration =
- m_pSourceElement->getPureDuration();
- HX_ASSERT(ulDuration == m_pSourceElement->getPureDuration() ||
- m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase);
- }
- }
- }
- cleanup:
- if (m_pDependent && ((UINT32)-1 != m_pSourceElement->m_ulDelay))
- {
- HX_ASSERT(WAY_IN_THE_FUTURE >= m_pSourceElement->m_ulDuration +
- m_pSourceElement->m_ulDelay); // 59584(media version) & 50848
- }
- if(m_pDependent &&
- // /Helps fix PR 66391: If we removed this track because it fell
- // completely outside its parent's time bounds, then we shouldn't
- // update our dependent, but rather allow further processing of the
- // parent seq's setDuration() to remove it's track:
- !bTrackStartsTooLateSoTrackRemoved &&
- // /Helps fix some timing interop cases in the 11.2-11.9 range:
- ((UINT32)-1 != m_pSourceElement->m_ulDelay) &&
- // /Helps fix case where as-yet-unresolved end of seq child should
- // *not* be used to resolve next sibling's begin: (PR 50848)
- WAY_IN_THE_FUTURE > m_pSourceElement->m_ulDuration +
- m_pSourceElement->m_ulDelay) // /+delay for PR 59584-related bug.
- {
- //Removed the addition of m_pSourceElement->m_ulDelay from the
- // source's duration because the source's duration already includes
- // its delay; we don't want to count the delay twice. Fixes PR 13983:
- // /*XXXEH- UNFIXES 13983 by adding back in the ...m_ulDelay addition;
- // the full fix for 13983 requires keeping track of begin=... delay
- // (as opposed to seq-related delay) and then subtracting that begin
- // delay from the m_ulDelay below:
- adjustDependentDuration(m_pDependent);
- // /XXXEH- TODO: figure out if we need to claim this is being set by
- // "parent" (which is really time base) so clip-begin-like action can
- // occur; I don't think so, however:
- // /XXXEH- I think this fixes PR 13983 without breaking other stuff,
- // but need to make sure:
- // /Don't propagate delay of sourceElement (PR 13983) in case its
- // duration already includes its begin offset:
- ULONG32 ulDelayOfSourceElem = m_pSourceElement->m_ulDelay +
- m_pSourceElement->m_ulDuration;
- if (m_pSourceElement->m_bBeginOffsetSet &&
- m_pSourceElement->m_lBeginOffset > 0)
- {
- ulDelayOfSourceElem =
- ((INT32)ulDelayOfSourceElem >
- m_pSourceElement->m_lBeginOffset ?
- ulDelayOfSourceElem - m_pSourceElement->m_lBeginOffset :
- 0);
- #if defined(XXXEH_DEBUG)
- HX_ASSERT(!m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase &&
- "ehodge: don't count delay twice!");
- #endif
- if (m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase)
- {
- HX_ASSERT(m_pSourceElement->m_ulBeginOffsetFromSyncBase <=
- m_pSourceElement->m_lBeginOffset); // /PR 6XXXX.
- }
- }
- // /If this is a repeat element and the first iteration element
- // was clipped due to a negative begin offset, we want to use the
- // full duration for this clip:
- if (m_pDependent->m_pSourceElement->m_pNode->m_repeatTag ==
- RepeatReplica && m_pSourceElement->m_lBeginOffset < 0)
- {
- ULONG32 ulRepeatIterationFullDur =
- m_pSourceElement->m_ulOriginalDuration -
- m_pSourceElement->m_lBeginOffset;
- if ((UINT32)-1 != m_pSourceElement->m_ulOriginalDuration)
- {
- m_pDependent->m_pSourceElement->m_ulDuration =
- ulRepeatIterationFullDur;
- }
- }
- if (WAY_IN_THE_FUTURE < ulDelayOfSourceElem)
- {
- HX_ASSERT(WAY_IN_THE_FUTURE == ulDelayOfSourceElem && "PR 59584");
- ulDelayOfSourceElem = WAY_IN_THE_FUTURE; // /For PR 59584.
- }
- m_pDependent->setDelay(ulDelayOfSourceElem, FALSE);
- }
- m_pParser->m_pTimelineElementManager->notify(m_pID);
- }
- void
- CSmilTimelineElement::setMaxDuration(UINT32 ulMaxDuration)
- {
- m_bMaxDurationSet = TRUE;
- m_pSourceElement->m_ulMaxDuration = ulMaxDuration;
- }
- void
- CSmilTimelineElement::adjustDependentDuration(CSmilTimelineElement* pDependent)
- {
- if (m_pParent)
- {
- m_pParent->adjustDependentDuration(m_pDependent);
- }
- }
- void
- CSmilTimelineElement::resetDelay(UINT32 ulDelay)
- {
- INT32 lAdjustedDelay = 0;
- UINT32 ulPriorDelay = m_pSourceElement->m_ulDelay;
- if(m_pSourceElement->m_bBeginOffsetSet)
- {
- lAdjustedDelay = (INT32)ulDelay + m_pSourceElement->m_lBeginOffset;
- m_pSourceElement->m_ulDelay = lAdjustedDelay > 0?lAdjustedDelay:0;
- }
- else
- {
- m_pSourceElement->m_ulDelay = ulDelay;
- }
-
- if (m_pDependent && m_bDurationSet)
- {
- #if defined(XXXEH_WAIT_UNTIL_getCurrentScheduledStopTime_IS_FIXED_WHEN_BEGINOFFSETSET_20011022)
- ULONG32 ulTotalDelay = 0;
- if (m_pSourceElement->m_bCurBeginIsOffsetFromSyncBase &&
- m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase)
- {
- HX_ASSERT(0 && "ehodge: CHANGE NOT TESTED!");
- }
- if (HXR_OK !=
- m_pSourceElement->getCurrentScheduledStopTime(ulTotalDelay))
- {
- goto doneSettingDependent;
- }
- #else
- ULONG32 ulTotalDelay = m_pSourceElement->m_ulDelay +
- m_pSourceElement->m_ulDuration;
- // /Helps fix PR 6XXXX(media version): if delay is already packed
- // into the duration, then don't count it twice (as can happen in
- // <seq><ref begin="1s" .../><ref begin="1s" .../>...):
- if (m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase)
- {
- HX_ASSERT(m_pSourceElement->m_ulBeginOffsetFromSyncBase != (UINT32)-1);
- /*OK[]*/ if (m_pSourceElement->m_ulBeginOffsetFromSyncBase !=(UINT32)-1)
- {
- HX_ASSERT(m_pSourceElement->m_ulBeginOffsetFromSyncBase <
- ulTotalDelay);
- if (m_pSourceElement->m_ulBeginOffsetFromSyncBase <
- ulTotalDelay)
- {
- ulTotalDelay -=
- m_pSourceElement->m_ulBeginOffsetFromSyncBase;
- }
- }
- }
- #endif
- if (WAY_IN_THE_FUTURE < ulTotalDelay)
- {
- HX_ASSERT(WAY_IN_THE_FUTURE == ulTotalDelay && "PR 59584");
- ulTotalDelay = WAY_IN_THE_FUTURE; // /For PR 59584.
- }
-
- #if defined(_DEBUG) && defined(XXXEH_DEBUGOUT_ADDDURATION)
- {
- FILE* f1 = ::fopen("c:\smil2AddDuration.txt", bFirstTimeAddDurDebugout?
- ADDDURATION_DEBUGOUT_STR_NEW_FILE :
- ADDDURATION_DEBUGOUT_STR_APPEND_TO_FILE );
- ::fprintf(f1, "nt%s:CSmilTimelineElement::resetDelay(%lu):from %lu to %lu;"
- "tresetting dependent (%s)'s delay to %lun", (const char*)m_pID,
- ulDelay, ulPriorDelay, m_pSourceElement->m_ulDelay,
- (const char*)m_pDependent->m_pID, ulTotalDelay);
- ::fclose(f1);
- bFirstTimeAddDurDebugout = FALSE;
- }
- #endif
-
- m_pDependent->resetDelay(ulTotalDelay);
- }
- #if defined(XXXEH_WAIT_UNTIL_getCurrentScheduledStopTime_IS_FIXED_WHEN_BEGINOFFSETSET_20011022)
- doneSettingDependent:
- #endif
- if (m_pSourceElement->m_bRendererInitialized)
- {
- m_pParser->resetTimelineElementDelay(m_pID, m_pSourceElement->m_ulDelay,
- ulPriorDelay);
- }
- // /(Added while fixing PR 59851) Let others know our begin time changed:
- m_pParser->m_pTimelineElementManager->notify(m_pID);
- }
- void
- CSmilTimelineElement::resetDuration(UINT32 ulDuration)
- {
- INT32 lAdjustedDuration = 0;
- UINT32 ulPriorPureDuration = m_pSourceElement->getPureDuration();
-
- if(m_pSourceElement->m_bBeginOffsetSet)
- {
- if (!m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase)
- {
- m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase =
- TRUE; // /=TRUE,not ULONG32. Helps fix PR 68190.
- }
- lAdjustedDuration = (INT32)ulDuration + m_pSourceElement->m_lBeginOffset;
- m_pSourceElement->m_ulDuration = lAdjustedDuration > 0?lAdjustedDuration:0;
- }
- else
- {
- m_pSourceElement->m_ulDuration = ulDuration;
- }
- if(m_pParent)
- {
- // /Added surrounding if() to prevent adjusting dur of parent when
- // parent has clearly imposed its dur on *this (helps fix PR 58568)
- if (!m_pSourceElement->m_bCurEndClippedByParent)
- {
- m_pParent->adjustDuration();
- }
- }
- if(m_pDependent)
- {
- #if defined(XXXEH_WAIT_UNTIL_getCurrentScheduledStopTime_IS_FIXED_WHEN_BEGINOFFSETSET_20011022)
- ULONG32 ulTotalDelay = 0;
- if (m_pSourceElement->m_bCurBeginIsOffsetFromSyncBase &&
- m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase)
- {
- HX_ASSERT(0 && "ehodge: CHANGE NOT TESTED!");
- }
- if (HXR_OK !=
- m_pSourceElement->getCurrentScheduledStopTime(ulTotalDelay))
- {
- goto doneSettingDependent;
- }
- #else
- ULONG32 ulTotalDelay = m_pSourceElement->m_ulDelay +
- m_pSourceElement->m_ulDuration;
- // /Helps fix PR 6XXXX(media version): if delay is already packed
- // into the duration, then don't count it twice (as can happen in
- // <seq><ref begin="1s" .../><ref begin="1s" .../>...):
- if (m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase)
- {
- HX_ASSERT(m_pSourceElement->m_ulBeginOffsetFromSyncBase != (UINT32)-1);
- /*OK[]*/ if (m_pSourceElement->m_ulBeginOffsetFromSyncBase !=(UINT32)-1)
- {
- HX_ASSERT(m_pSourceElement->m_ulBeginOffsetFromSyncBase <
- ulTotalDelay);
- if (m_pSourceElement->m_ulBeginOffsetFromSyncBase <
- ulTotalDelay)
- {
- ulTotalDelay -=
- m_pSourceElement->m_ulBeginOffsetFromSyncBase;
- }
- }
- }
- #endif
- if (WAY_IN_THE_FUTURE < ulTotalDelay)
- {
- HX_ASSERT(WAY_IN_THE_FUTURE == ulTotalDelay && "PR 59584");
- ulTotalDelay = WAY_IN_THE_FUTURE; // /For PR 59584.
- }
-
- #if defined(_DEBUG) && defined(XXXEH_DEBUGOUT_ADDDURATION)
- {
- FILE* f1 = ::fopen("c:\smil2AddDuration.txt", bFirstTimeAddDurDebugout?
- ADDDURATION_DEBUGOUT_STR_NEW_FILE :
- ADDDURATION_DEBUGOUT_STR_APPEND_TO_FILE );
- ::fprintf(f1, "nt%s:CSmilTimelineElement::resetDuration(%lu):from %lu to %lu;"
- "tresetting dependent (%s)'s delay to %lun", (const char*)m_pID,
- ulPriorPureDuration, ulDuration, m_pSourceElement->m_ulDuration,
- (const char*)m_pDependent->m_pID, ulTotalDelay);
- ::fclose(f1);
- bFirstTimeAddDurDebugout = FALSE;
- }
- #endif
-
- // /Helps fix PR 66391; if parent clipped our duration to 0, don't
- // update dependent; that'll be handled in parent seq's setDuration():
- if (0 != ulDuration && !m_pSourceElement->m_bCurEndClippedByParent)
- {
- m_pDependent->resetDelay(ulTotalDelay);
- }
- }
- #if defined(XXXEH_WAIT_UNTIL_getCurrentScheduledStopTime_IS_FIXED_WHEN_BEGINOFFSETSET_20011022)
- doneSettingDependent:
- #endif
- m_pParser->m_pTimelineElementManager->notify(m_pID);
- }
- void
- CSmilTimelineElement::adjustDuration()
- {
- // no-op
- return;
- }
- HX_RESULT
- CSmilTimelineElement::handlePrefetchFinished(UINT32 ulTimeFinished)
- {
- HX_RESULT pnr = HXR_FAILED;
- 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:
- // /Combining handling of SMILEventSourceBegin and SMILEventSourceClock
- // fixes SMIL 1.0-syntax PR 112740; the ancient fix for the SMIL2-syntax
- // version is already in the below code; it's about time we combine
- // this code, anyway. (SMILEventSourceClock is only used in SMIL 1.0-
- // syntax syncArcs with clock offsets) :
- if ( (m_pSourceElement->m_nBeginEventSourceTag == SMILEventSourceBegin ||
- m_pSourceElement->m_nBeginEventSourceTag == SMILEventSourceClock) &&
- 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()
- // 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_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);
- 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;
- #if defined(XXXEH_TESTING)
- HX_ASSERT(m_pSourceElement->m_ulDuration);
- #endif
- }
- }
- }
-
- // /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;
- m_pSourceElement->m_ulDuration = (UINT32)(lSum<0 ? 0 : lSum);
- }
- bNeedToResolveBeginTimeListVals = TRUE;
- if (HXR_OK == m_pParser->adjustForNegativeOffset(m_pID))
- {
- if (!m_pSourceElement->m_bHasBeenScheduled ||
- // /Fixes PR 50588 (case2): if restarting, hasBeenSched
- // will still be true, so check if inserted instead:
- (m_pSourceElement->m_bIsRestarting &&
- !m_pSourceElement->m_bInsertedIntoTimeline) )
- {
- // /See note in code above that handles
- // m_nBeginEventSourceTag == SMILEventSourceBegin:
- 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)
- {
- // /See note in code above that handles
- // m_nBeginEventSourceTag == SMILEventSourceBegin:
- m_bDelaySet = bPreviousDelaySetVal;
- // /Fixes "foo.end" version of 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 foo.end version of
- // 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);
- }
- }
- // /Fixes (part of) SMIL 2.0 Interop Timing #28.9:
- // If already scheduled and possibly even playing, we need to
- // reset the timeline element's delay:
- else if (ulPriorDelay != m_pSourceElement->m_ulDelay)
- {
- // /Get the matching begin time val, resolve it, and put
- // it in the pending list:
- LISTPOSITION lPos = NULL;
- if (m_pSourceElement->m_pBeginTimeList && NULL !=
- (lPos = m_pSourceElement->m_pBeginTimeList->
- GetHeadPosition()) )
- {
- while (lPos)
- {
- SmilTimeValue* pTmpVal = (SmilTimeValue*)
- m_pSourceElement->m_pBeginTimeList->
- GetNext(lPos);
- if (pTmpVal)
- {
- if (SmilTimeSyncBase == pTmpVal->m_type)
- {
- if (!pTmpVal->isTimeResolved())
- {
- if (pTmpVal->m_idRef ==
- pEventElement->m_pID)
- {
- BOOL bATimeWasResolved;
- m_pSourceElement->resolveSyncArcTimeValues(
- m_pSourceElement->m_ulDelay +
- (bUseBeginOffsetForPendingBeginList?
- m_pSourceElement->m_lBeginOffset:0),
- (const char*)pEventElement->m_pID,
- SmilBeginTimeList, bATimeWasResolved,
- TRUE, m_pParser);
- bNeedToResolveBeginTimeListVals = FALSE;
- }
- }
- else
- {
- // /else get from pending and change it!
- // See PR 50588 (case 2: begin="x.end")
- }
- }
- }
- }
- }
- }
- }
- }
- }
- SMILNode* pSyncNode = pSyncBaseNode;
- HX_ASSERT(pSyncNode && pSyncNode->m_pElement);
- //[SMIL 1.0 compliance] Fixes PR 16629:
- //Next, let's see if we have an end event to resolve:
- // /XXXEH- TODO 20010525: we need to see if there already is an end time
- // that is prior to this new one and is after a begin time; if so, then
- // we want to stick this new one into the pending end time list rather
- // than use it right away:
- // /Combining handling of SMILEventSourceBegin and SMILEventSourceClock
- // fixes SMIL 1.0-syntax version of PR 63622 (part 4) where the fix for
- // part 2 gets resused if we share this code; it's about time we combine
- // this code, anyway:
- if ( (m_pSourceElement->m_nEndEventSourceTag == SMILEventSourceBegin ||
- m_pSourceElement->m_nEndEventSourceTag == SMILEventSourceClock) &&
- m_pSourceElement->m_EndEventSourceID == pEventElement->m_pID)
- {
- if(pEventElement->m_bDelaySet)
- {
- m_bDurationSet = TRUE;
- LONG32 lSum =(LONG32)pEventElement->m_pSourceElement->m_ulDelay +
- m_pSourceElement->m_lEndEventClockValue;
- // /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 (m_pSourceElement->m_bBeginOffsetSet)
- {
- if (pSyncNode && pSyncNode->m_pElement)
- {
- ULONG32 ulSyncBaseDelay =
- pSyncNode->m_pElement->m_ulDelay;
- HX_ASSERT((UINT32)-1 != ulSyncBaseDelay);
- if ((UINT32)-1 != ulSyncBaseDelay)
- {
- HX_ASSERT(m_pSourceElement->m_ulDelay >=
- ulSyncBaseDelay);
- if (m_pSourceElement->m_ulDelay > ulSyncBaseDelay)
- {
- lSum -= (LONG32)ulSyncBaseDelay;
- }
-
- }
- }
- }
- // /Checking these two conditionals helps fix PR 63622 (part 2):
- else if (m_bDelaySet && m_pSourceElement->m_ulDelay!=(UINT32)-1)
- {
- // /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");
- lSum = (lSum<0? 0 : lSum); //clip off negative vals.
- m_pSourceElement->m_ulDuration = (UINT32)lSum;
- // /Fixes case where parent dur was overriding this new
- // m_ulDuration, above, in this's subsequent setDuration(d,TRUE)
- if (WAY_IN_THE_FUTURE == m_pSourceElement->m_ulAuthoredDur)
- {
- // /Change "core-tricking" value back to unset:
- m_pSourceElement->m_ulAuthoredDur = (UINT32)-1;
- }
- // /Fixes case where both dur=d & end=x.begin were specified;
- // use the lesser of the two (part 4 of PR 71386):
- else if (m_pSourceElement->m_bHasExplicitDur &&
- (UINT32)-1 != m_pSourceElement->m_ulAuthoredDur &&
- m_pSourceElement->m_ulAuthoredDur < (UINT32)lSum)
- {
- m_pSourceElement->m_ulDuration =
- m_pSourceElement->m_ulAuthoredDur;
- }
- bNeedToResolveEndTimeListVals = TRUE;
- // /More of fix for PR 63622 (part 2): if our delay isn't set, then
- // when it does resolve, treat it as an end, not a relative dur:
- if (!m_bDelaySet || m_pSourceElement->m_ulDelay==(UINT32)-1)
- {
- /* Removing this doesn't (now) affect PR 63622 part 2, which
- * still plays fine, while removing it *does* fix PR 81256
- * where an element wasn't restarting because its end time
- * (in its list) wasn't considered resolved on the next play:
- // /For PR 63622 (part 2): don't resolve end time(s) since
- // begin delay isn't resolved yet:
- bNeedToResolveEndTimeListVals = FALSE;
- */
- if (!m_pSourceElement->m_bEndOffsetSet)
- {
- m_pSourceElement->m_bEndOffsetSet = TRUE;
- m_pSourceElement->m_lEndOffset = (UINT32)lSum;
- }
- }
- // /Helps fix PR 63622 (part 2): changed this to "*else* if" since
- // we don't want to do anything until our begin delay is set:
- else if (HXR_OK == m_pParser->adjustForNegativeOffset(m_pID))
- {
- if (!m_pSourceElement->m_bHasBeenScheduled ||
- // /Fixes PR 50588 (case4): if restarting, hasBeenSched
- // will still be true, so check if inserted instead:
- (m_pSourceElement->m_bIsRestarting &&
- !m_pSourceElement->m_bInsertedIntoTimeline) )
- {
- bWasInsertedOntoTimeline = TRUE;
- m_pParser->insertTimelineElement(m_pID,
- m_pSourceElement->m_ulDelay);
- }
- // /Be sure to update the timeline; fixes variant of PR 59801
- // when end="x.begin" instead of end="x.end":
- else
- {
- m_pParser->resetTimelineElementDuration(
- (const char*)m_pSourceElement->m_pNode->m_id,
- m_pSourceElement->getPureDuration(),
- ulPriorPureDuration);
- m_pParser->m_pTimelineElementManager->notify(
- (const char*)m_pSourceElement->m_pNode->m_id);
- }
- }
- }
- }
- else if(m_pSourceElement->m_nEndEventSourceTag == SMILEventSourceEnd &&
- m_pSourceElement->m_EndEventSourceID == pEventElement->m_pID)
- {
- // /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)
- {
- m_bDurationSet = TRUE;
- LONG32 lSum =(LONG32)pEventElement->getDuration() +
- m_pSourceElement->m_lEndEventClockValue;
- // /If the event element has a delay, we need to add that
- // minus any beginOffset (if it's set); subtracting the begin
- // offset fixes "BUG-20000921_beginSyncArcOffBy5secInBlue.smi":
- if(pEventElement->m_bDelaySet)
- {
- lSum += (LONG32)pEventElement->m_pSourceElement->m_ulDelay;
- if (pEventElement->m_pSourceElement->m_bBeginOffsetSet &&
- pEventElement->m_pSourceElement->m_lBeginOffset > 0)
- {
- lSum -= pEventElement->m_pSourceElement->m_lBeginOffset;
- // /20020630- Find content that may be broken if this
- // asserts. If such a thing exists, change above call to
- // "...->getDuration()" to "...->getPureDuration()" and
- // then total delay:
- HX_ASSERT(pEventElement->m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase);
- }
- // /Final nail in PR 77406's coffin: if begin of event element
- // was event based and thus there's no m_bBeginOffsetSet but
- // there *is* a m_ulBeginOffsetFromSyncBase>0, then we need to
- // subtract that if it's included in the duration:
- else if (pEventElement->m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase &&
- pEventElement->m_pSourceElement->m_bCurBeginIsOffsetFromSyncBase &&
- pEventElement->m_pSourceElement->m_ulBeginOffsetFromSyncBase > 0)
- {
- lSum -= pEventElement->m_pSourceElement->m_ulBeginOffsetFromSyncBase;
- }
- }
- else
- {
- HX_ASSERT(pEventElement->m_bDelaySet);
- }
- // /lSum is now in global (group) time space. We need to convert
- // it into this's local time space:
- // /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 (m_pSourceElement->m_bBeginOffsetSet)
- {
- if (pSyncNode && pSyncNode->m_pElement)
- {
- ULONG32 ulSyncBaseDelay =
- pSyncNode->m_pElement->m_ulDelay;
- HX_ASSERT((UINT32)-1 != ulSyncBaseDelay);
- if ((UINT32)-1 != ulSyncBaseDelay)
- {
- HX_ASSERT(m_pSourceElement->m_ulDelay >=
- ulSyncBaseDelay);
- if (m_pSourceElement->m_ulDelay > ulSyncBaseDelay)
- {
- lSum -= (LONG32)ulSyncBaseDelay;
- }
-
- }
- }
- // /This fixes PR 8XXXZ (PR 63622 revisited): if begin is set and duration includes
- // that begin delay, subtract it from the sum & reset the flag:
- if (m_pSourceElement->m_bCurBeginIsOffsetFromSyncBase &&
- m_pSourceElement->m_ulBeginOffsetFromSyncBase > 0)
- {
- lSum -= m_pSourceElement->m_ulBeginOffsetFromSyncBase > 0?
- m_pSourceElement->m_ulBeginOffsetFromSyncBase : 0;
- m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase =
- FALSE;
- }
- }
- // /Checking these two conditionals helps fix PR 63622 (part 3):
- else if (m_bDelaySet && m_pSourceElement->m_ulDelay!=(UINT32)-1)
- {
- // /We need to remove our delay or it will get counted twice:
- // /XXXEH- 20020625: maybe subtract curBeginOffsetFromSyncBase (as 10 lines above) instead?:
- lSum -= m_pSourceElement->m_ulDelay;
- }
- HX_ASSERT(lSum >= 0 && "ehodge: handle neg delay propogation");
- lSum = (lSum<0? 0 : lSum); //clip off negative vals.
- m_pSourceElement->m_ulDuration = (UINT32)lSum;
- BOOL bDurationWasPreviouslyUnresolvedIndefinite = FALSE;
- // /Fixes case where parent dur was overriding this new
- // m_ulDuration, above, in this's subsequent setDuration(d,TRUE)
- if (WAY_IN_THE_FUTURE == m_pSourceElement->m_ulAuthoredDur)
- {
- bDurationWasPreviouslyUnresolvedIndefinite = TRUE;
- // /Change "core-tricking" value back to unset:
- m_pSourceElement->m_ulAuthoredDur = (UINT32)-1;
- }
- // /Fixes case where both dur=d & end=x.end were specified;
- // use the lesser of the two (part 2 of PR 71386):
- else if (m_pSourceElement->m_bHasExplicitDur &&
- (UINT32)-1 != m_pSourceElement->m_ulAuthoredDur &&
- m_pSourceElement->m_ulAuthoredDur < (UINT32)lSum)
- {
- m_pSourceElement->m_ulDuration =
- m_pSourceElement->m_ulAuthoredDur;
- }
- bNeedToResolveEndTimeListVals = TRUE;
-
- // /More of fix for PR 63622 (part 3): if our delay isn't set, then
- // when it does resolve, treat it as an end, not a relative dur:
- if (!m_bDelaySet || m_pSourceElement->m_ulDelay==(UINT32)-1)
- {
- /* Removing this doesn't (now) affect PR 63622 part 3, which
- * still plays fine, while removing it *does* fix PR 81256
- * where an element wasn't restarting because its end time
- * (in its list) wasn't considered resolved on the next play:
- // /For PR 63622 (part 3): don't resolve end time(s) since
- // begin delay isn't resolved yet:
- bNeedToResolveEndTimeListVals = FALSE;
- */
- if (!m_pSourceElement->m_bEndOffsetSet)
- {
- m_pSourceElement->m_bEndOffsetSet = TRUE;
- m_pSourceElement->m_lEndOffset = (UINT32)lSum;
- }
- }
- // /Helps fix PR 63622 (part 3): changed this to "*else* if" since
- // we don't want to do anything until our begin delay is set:
- else if (HXR_OK == m_pParser->adjustForNegativeOffset(m_pID))
- {
- if (!m_pSourceElement->m_bHasBeenScheduled ||
- // /Fixes PR 50588 (case5): if restarting, hasBeenSched
- // will still be true, so check if inserted instead:
- (m_pSourceElement->m_bIsRestarting &&
- !m_pSourceElement->m_bInsertedIntoTimeline) )
- {
- bWasInsertedOntoTimeline = TRUE;
- m_pParser->insertTimelineElement(m_pID,
- m_pSourceElement->m_ulDelay);
- }
- // /Fixes PR 59801: the fix for PR 50535, which enabled
- // inserting of an element into the timeline before its end
- // event is resolved (as is needed when end="foo.end" and foo
- // has an event-based end) caused parent to extend to that
- // WAY_IN_THE_FUTURE dur and never brought it back in when
- // the end time resolved, so here goes:
- // /Adding the if() part to the else helps fix PR 107724: don't
- // go through all this code if this element has not had its
- // duration altered by the code, above:
- else if (m_pSourceElement->getPureDuration() !=
- ulPriorPureDuration)
- {
- // /This fixes PR 70437 where temporary, indefinite
- // duration had been added to parent, earlier, while
- // waiting for when (or if) sync-arc'd element's end
- // ever resolves. Then, when it resolved, parent wasn't
- // being notified of this new duration, thus the temporary
- // indef duration remained as the presentation duration:
- m_bDurationSet=FALSE; // /Force override to new value.
- HX_ASSERT(m_pSourceElement->m_ulDuration ==
- m_pSourceElement->getPureDuration());
- m_pParser->durationResolved(
- (const char*)m_pSourceElement->m_pNode->m_id,
- m_pSourceElement->m_ulDuration, FALSE);
- m_pParser->resetTimelineElementDuration(
- (const char*)m_pSourceElement->m_pNode->m_id,
- m_pSourceElement->getPureDuration(),
- ulPriorPureDuration);
- // /Helps fix PR 107724: add duration to parent if
- // it was added before as unresolved indefinite:
- if (m_pSourceElement->m_bAddDurationAlreadyDone &&
- bDurationWasPreviouslyUnresolvedIndefinite)
- {
- m_pParent->addDuration(
- m_pSourceElement->m_ulDuration,
- m_pSourceElement->m_ulDelay,
- m_pSourceElement->m_ulBeginOffsetFromSyncBase,
- m_pID);
- }
- m_pParser->m_pTimelineElementManager->notify(
- (const char*)m_pSourceElement->m_pNode->m_id);
- }
- }
- }
- }
- BOOL bMoveNewlyResolvedsToPendingTimeList =
- !bWasInsertedOntoTimeline;
- if (bNeedToResolveBeginTimeListVals)
- {
- BOOL bATimeWasResolved;
- m_pSourceElement->resolveSyncArcTimeValues(
- m_pSourceElement->m_ulDelay +
- (bUseBeginOffsetForPendingBeginList?
- m_pSourceElement->m_lBeginOffset:0),
- (const char*)pEventElement->m_pID,
- SmilBeginTimeList, bATimeWasResolved,
- bMoveNewlyResolvedsToPendingTimeList,
- m_pParser);
- }
- if (bNeedToResolveEndTimeListVals)
- {
- // /Fixes PR 81828: if delay is unresolved but end time was just
- // resolved, above, then use end not the invalid sum of dur+delay:
- ULONG32 ulEndTime = m_pSourceElement->m_ulDuration +
- m_pSourceElement->m_ulDelay;
- if ((UINT32)-1 == m_pSourceElement->m_ulDelay ||
- (UINT32)-1 == m_pSourceElement->m_ulDuration)
- {
- ulEndTime = m_pSourceElement->m_lEndOffset;
- }
- // /Helps fix PR 79699 (case where trackDurationResolved call order
- // is: flash, msd, vid):
- else if (m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase &&
- m_pSourceElement->m_ulBeginOffsetFromSyncBase > 0)
- {
- ulEndTime -= m_pSourceElement->m_ulBeginOffsetFromSyncBase;
- }
- BOOL bATimeWasResolved;
- m_pSourceElement->resolveSyncArcTimeValues(
- // /Use dur+delay, not just delay here (as can be proven when
- // doing the following: begin="foo.end" end="foo.end+5s"
- // where foo.begin > 0:
- ulEndTime,
- (const char*)pEventElement->m_pID,
- SmilEndTimeList, bATimeWasResolved,
- bMoveNewlyResolvedsToPendingTimeList,
- m_pParser);
- }
- // XXXMEH - we need to check here if we should
- // update the remove time
- checkElementFillBehavior();
- }
- #if 0
- void
- CSmilTimelineElement::setEvent(SMILEventSourceTag eTag,
- SMILSyncAttributeTag aTag,
- const char* pEventSourceID,
- UINT32 ulEventClockValue)
- {
- m_eEventSourceTag = eTag;
- m_eSyncAttributeTag = aTag;
- if(pEventSourceID)
- {
- m_pEventSourceID = new char[strlen(pEventSourceID)+1];
- strcpy(m_pEventSourceID, pEventSourceID); /* Flawfinder: ignore */
- m_pParser->m_pTimelineElementManager->addNotification(pEventSourceID, this);
- }
- m_ulEventClockValue = ulEventClockValue;
- }
- #endif
- void
- CSmilTimelineElement::addChild(CSmilTimelineElement* pChild)
- {
- if(!m_pChildren)
- {
- m_pChildren = new CHXSimpleList;
- }
- m_pChildren->AddTail(pChild);
- pChild->setParent(this);
- }
- UINT32
- CSmilTimelineElement::getDuration()
- {
- return m_pSourceElement->m_ulDuration;
- }
- UINT32
- CSmilTimelineElement::getDelay()
- {
- return m_pSourceElement->m_ulDelay;
- }
- void
- CSmilTimelineElement::dump()
- {
- }
- void CSmilTimelineElement::checkChildrenFillBehavior()
- {
- if (m_pChildren && m_pParser)
- {
- LISTPOSITION pos = m_pChildren->GetHeadPosition();
- while (pos)
- {
- CSmilTimelineElement* pTime =
- (CSmilTimelineElement*) m_pChildren->GetNext(pos);
- if (pTime &&
- pTime->m_pSourceElement &&
- pTime->m_pSourceElement->m_pNode)
- {
- const char* pszID = (const char*) pTime->m_pSourceElement->m_pNode->m_id;
- UINT32 ulComputedTime = 0;
- HX_RESULT retVal = m_pParser->computeRemoveTime(pszID, ulComputedTime);
- if (SUCCEEDED(retVal))
- {
- // /#define XXXEHODGE_DEBUG_REMOVE_TIME_OF_VISUAL_ELEMENT
- #if defined(_DEBUG) && defined(XXXEHODGE_DEBUG_REMOVE_TIME_OF_VISUAL_ELEMENT)
- {
- FILE* f1 = ::fopen("c:\smil2AddDuration.txt", "a+");
- ::fprintf(f1, "checkChildrenFillBehavior() of %s, computed time=%lu, m_ulRemoveTime=%lu, m_ulDelay=%lu, m_ulDuration=%lun",
- pszID, ulComputedTime, pTime->m_pSourceElement->m_ulRemoveTime, pTime->m_pSourceElement->m_ulDelay, pTime->m_pSourceElement->m_ulDuration);
- ::fclose(f1);
- }
- #endif
- // We've successfully computed the remove time - does
- // this remove time match when we have the hide event scheduled?
- if (ulComputedTime != pTime->m_pSourceElement->m_ulRemoveTime)
- {
- #if defined(_DEBUG) && defined(XXXEHODGE_DEBUG_REMOVE_TIME_OF_VISUAL_ELEMENT)
- {
- FILE* f1 = ::fopen("c:\smil2excl.txt", "a+");
- ::fprintf(f1, "tcheckChildrenFillBehavior() called [%s]->updateRemoveTime(%lu <--(%lu) ), m_ulDelay=%lu, m_ulDuration=%lun",
- pszID, ulComputedTime, pTime->m_pSourceElement->m_ulRemoveTime, pTime->m_pSourceElement->m_ulDelay, pTime->m_pSourceElement->m_ulDuration);
- ::fclose(f1);
- }
- #endif
- // We need to update the hide event
- pTime->m_pSourceElement->updateRemoveTime(ulComputedTime);
- }
- // If this child has a fill="freeze" or a fill="hold",
- // then we need to check this child's children
- if (pTime->m_pSourceElement->m_eActualFill == FillFreeze ||
- pTime->m_pSourceElement->m_eActualFill == FillHold)
- {
- pTime->checkChildrenFillBehavior();
- }
- }
- }
- }
- }
- }
- void CSmilTimelineElement::checkElementFillBehavior()
- {
- if (m_pSourceElement &&
- m_pSourceElement->m_pNode)
- {
- const char* pszID = (const char*) m_pSourceElement->m_pNode->m_id;
- UINT32 ulComputedTime = 0;
- HX_RESULT retVal = m_pParser->computeRemoveTime(pszID, ulComputedTime);
- if (SUCCEEDED(retVal))
- {
- // We've successfully computed the remove time - does
- // this remove time match when we have the hide event scheduled?
- if (ulComputedTime != m_pSourceElement->m_ulRemoveTime)
- {
- // char szDbgStr[128];
- // DEBUGPRINTF(szDbgStr, "Updating id=%s remove time from %lu to %lun",
- // pszID, m_pSourceElement->m_ulRemoveTime, ulComputedTime);
- // We need to update the hide event
- m_pSourceElement->updateRemoveTime(ulComputedTime);
- }
- }
- }
- }
- void CSmilTimelineElement::setParExclDuration(UINT32 ulDuration, BOOL bSetFromParent)
- {
- m_pSourceElement->m_ulDuration = ulDuration;
- // /Don't go past end of parent; fixes PR65741-related event-begun par
- if (m_pSourceElement->m_ulDuration > m_pSourceElement->m_ulMaxDuration)
- {
- m_pSourceElement->m_ulDuration = m_pSourceElement->m_ulMaxDuration;
- }
- m_bDurationSet = TRUE;
- if(m_pChildren &&
- // /If not set from parent, make sure we've completely resolved
- // our duration before forcing it on the kids (broken by fix for
- // PR 61174(version1). Fixes PR 56686 version 7:
- (bSetFromParent || m_pSourceElement->m_bAddDurationAlreadyDone
- // /Explicit end or dur, so OK to possibly clip children; helps
- // reduce cases where PR 65676 occurs by setting max durs on kids:
- || m_pSourceElement->m_bHasExplicitEnd
- || m_pSourceElement->m_bHasExplicitDur))
- {
- CHXSimpleList::Iterator i = m_pChildren->Begin();
- for(; i != m_pChildren->End(); ++i)
- {
- CSmilTimelineElement* pElement = (CSmilTimelineElement*)(*i);
- pElement->setDuration(m_pSourceElement->m_ulDuration, TRUE);
- }
- }
- //[SMIL 1.0 comliance] Helps fix PR 14420 and 23025
- m_pParser->m_pTimelineElementManager->notify(m_pID);
- }
- void CSmilTimelineElement::setParExclMaxDuration(UINT32 ulMaxDuration)
- {
- HX_ASSERT(m_pChildren);
- m_bMaxDurationSet = TRUE;
- m_pSourceElement->m_ulMaxDuration = ulMaxDuration;
- if (m_pChildren && m_bDelaySet)
- {
- HX_ASSERT((UINT32)-1 != m_pSourceElement->m_ulDelay);
- CHXSimpleList::Iterator i = m_pChildren->Begin();
- for(; i != m_pChildren->End(); ++i)
- {
- CSmilTimelineElement* pElement = (CSmilTimelineElement*)(*i);
- pElement->setMaxDuration(ulMaxDuration);
- }
- }
- }
- void CSmilTimelineElement::parExclElementResolved(CSmilTimelineElement* pEventElement)
- {
- // /Fixes PR 56233 (par version): if this par is resolving an end time
- // based on another element's timing and that other element is a
- // descendant of this par, then we'll get in an infinite loop when this
- // par clips its child's end, causing the child to update its end, causing
- // this par to get another elementResolved, ad infinitum. Now, we lock
- // elementResolved() on this element by setting its m_bInElementResolved
- // flag and resetting it only when this method has completed:
- if (m_bInElementResolved)
- {
- goto cleanup;
- }
- m_bInElementResolved = TRUE;
- //First, let's see if we have a begin event to resolve:
- // /Combine handling of SMILEventSourceBegin and SMILEventSourceClock;
- // the latter is only used in SMIL 1.0-syntax syncArcs with clock offsets:
- if ( (m_pSourceElement->m_nBeginEventSourceTag == SMILEventSourceBegin ||
- m_pSourceElement->m_nBeginEventSourceTag == SMILEventSourceClock) &&
- m_pSourceElement->m_BeginEventSourceID == pEventElement->m_pID)
- {
- if(pEventElement->m_bDelaySet)
- {
- // /Note: no longer subtracting pEventElement->m_pSourceElement->
- // m_ulBeginOffsetFromSyncBase from the sum in the following
- // if/else fixes PR 66352 while allowing PR 14420 (SMIL2-excl
- // version) to still work
- //[SMIL 1.0 Compliance] Helps fix 14420:
- if (m_bNonEventDelaySet)
- {
- //Add non-event delay to syncArc element delay + clock offset:
- //Do the following in case sum is negative; if so, we
- // want to use zero.
- LONG32 lSum =
- (LONG32)pEventElement->m_pSourceElement->m_ulDelay +
- m_pSourceElement->m_lBeginEventClockValue;
- HX_ASSERT(lSum >= 0 && "ehodge: handle neg delay propogation");
- lSum = (lSum<0? 0 : lSum); //clip off negative vals.
- m_pSourceElement->m_ulDelay = m_ulNonEventDelay + (ULONG32)lSum;
- }
- else
- {
- //Just set delay to syncArc element delay + clock offset:
- //Do the following in case sum is negative; if so, we
- // want to use zero.
- LONG32 lSum =
- (LONG32)pEventElement->m_pSourceElement->m_ulDelay +
- m_pSourceElement->m_lBeginEventClockValue;
- HX_ASSERT(lSum >= 0 && "ehodge: handle neg delay propogation");
- lSum = (lSum<0? 0 : lSum); //clip off negative vals.
- m_pSourceElement->m_ulDelay = (ULONG32)lSum;
- m_ulNonEventDelay = 0;
- }
- m_bNonEventDelaySet = m_bDelaySet = TRUE;
- if(m_pChildren)
- {
- CHXSimpleList::Iterator i = m_pChildren->Begin();
- for(; i != m_pChildren->End(); ++i)
- {
- CSmilTimelineElement* pElement =
- (CSmilTimelineElement*)(*i);
- pElement->setDelay(m_pSourceElement->m_ulDelay, TRUE);
- }
- }
- }
- }
- else if(m_pSourceElement->m_nBeginEventSourceTag == SMILEventSourceEnd &&
- m_pSourceElement->m_BeginEventSourceID == pEventElement->m_pID)
- {
- // /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)
- {
- //[SMIL 1.0 Compliance] Helps fix 14420:
- if (m_bNonEventDelaySet)
- {
- //Add non-event delay to syncArc element end + clock offset:
- LONG32 lSum =
- (LONG32)pEventElement->m_pSourceElement->m_ulDuration +
- (LONG32)pEventElement->m_pSourceElement->m_ulDelay +
- m_pSourceElement->m_lBeginEventClockValue;
- HX_ASSERT(lSum >= 0 && "ehodge: handle neg delay propogation");
- lSum = (lSum<0? 0 : lSum); //clip off negative vals.
- m_pSourceElement->m_ulDelay = m_ulNonEventDelay + (ULONG32)lSum;
- }
- else
- {
- //Just set delay to syncArc element end + clock offset:
- //Do the following in case sum is negative; if so, we
- // want to use zero.
- LONG32 lSum =
- (LONG32)pEventElement->m_pSourceElement->m_ulDuration +
- (LONG32)pEventElement->m_pSourceElement->m_ulDelay +
- m_pSourceElement->m_lBeginEventClockValue;
- HX_ASSERT(lSum >= 0 && "ehodge: handle neg delay propogation");
- lSum = (lSum<0? 0 : lSum); //clip off negative vals.
- m_pSourceElement->m_ulDelay = (ULONG32)lSum;
- m_ulNonEventDelay = 0;
- }
- m_bNonEventDelaySet = m_bDelaySet = TRUE;
- if(m_pChildren)
- {
- CHXSimpleList::Iterator i = m_pChildren->Begin();
- for(; i != m_pChildren->End(); ++i)
- {
- CSmilTimelineElement* pElement =
- (CSmilTimelineElement*)(*i);
- pElement->setDelay(m_pSourceElement->m_ulDelay, TRUE);
- }
- }
- }
- }
-
- // /Combine handling of SMILEventSourceBegin and SMILEventSourceClock;
- // the latter is only used in SMIL 1.0-syntax syncArcs with clock offsets:
- if ( (m_pSourceElement->m_nEndEventSourceTag == SMILEventSourceBegin ||
- m_pSourceElement->m_nEndEventSourceTag == SMILEventSourceClock) &&
- m_pSourceElement->m_EndEventSourceID == pEventElement->m_pID)
- {
- if(pEventElement->m_bDelaySet)
- {
- LONG32 lSum =(LONG32)pEventElement->m_pSourceElement->m_ulDelay +
- m_pSourceElement->m_lEndEventClockValue;
- if (m_bDelaySet)
- {
- // /Fixes bug where the following had a dur that didn't
- // account for its offset:
- // <par begin="3s" end="foo.begin+5s" />
- lSum -= m_pSourceElement->m_ulDelay;
- }
- HX_ASSERT(lSum >= 0 && "ehodge: handle neg delay propogation");
- lSum = (lSum<0? 0 : lSum); //clip off negative vals.
- // /Fixes PR 43068:
- m_bDurationSet = FALSE; // /We want to force override to lSum.
- parExclDurationResolved((ULONG32)lSum, TRUE);
- }
- }
- else if(m_pSourceElement->m_nEndEventSourceTag == SMILEventSourceEnd &&
- m_pSourceElement->m_EndEventSourceID == pEventElement->m_pID)
- {
- // /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)
- {
- LONG32 lSum =(LONG32)pEventElement->getDuration() +
- m_pSourceElement->m_lEndEventClockValue;
- // /If the event element has a delay, we need to add that
- // minus any beginOffset (if it's set):
- if(pEventElement->m_bDelaySet)
- {
- lSum += (LONG32)pEventElement->m_pSourceElement->m_ulDelay;
- if (pEventElement->m_pSourceElement->m_bBeginOffsetSet)
- {
- HX_ASSERT(0 && "ehodge: does this code work?!");
- lSum -= pEventElement->m_pSourceElement->m_lBeginOffset;
- }
- }
- if (m_bDelaySet)
- {
- // /Fixes bug where the following had a dur that didn't
- // account for its offset:
- // <par begin="3s" end="foo.end+5s" />
- lSum -= m_pSourceElement->m_ulDelay;
- }
- HX_ASSERT(lSum >= 0 && "ehodge: handle neg delay propogation");
- lSum = (lSum<0? 0 : lSum); //clip off negative vals.
- // /Fixes PR 43068:
- m_bDurationSet = FALSE; // /We want to force override to lSum.
- parExclDurationResolved((ULONG32)lSum, TRUE);
- }
- }
- m_bInElementResolved = FALSE;
- cleanup:
- return;
- }
- void CSmilTimelineElement::parExclDurationResolved(UINT32 ulDuration, BOOL bUpdateChildren)
- {
- #if defined(_DEBUG) && defined(XXXEH_DEBUGOUT_ADDDURATION)
- {
- FILE* f1 = ::fopen("c:\smil2AddDuration.txt", bFirstTimeAddDurDebugout?
- ADDDURATION_DEBUGOUT_STR_NEW_FILE :
- ADDDURATION_DEBUGOUT_STR_APPEND_TO_FILE );
- ::fprintf(f1, "CSmilTimelineElement{%s}::parExclDurationResolved(dur=%lu, bUpdateChildren=%d, "
- "m_bDurationSet=%sE (cur m_ulDuration=%lu) m_bAddDurationAlreadyDone=%dn",
- (const char*)m_pID, ulDuration, bUpdateChildren, m_bDurationSet?"TRU":"FALS",
- m_pSourceElement->m_ulDuration, m_pSourceElement->m_bAddDurationAlreadyDone);
- ::fclose(f1);
- bFirstTimeAddDurDebugout = FALSE;
- }
- #endif
- if(!m_bDurationSet ||
- // /Final fix for PR 52110: we need to make sure parent and
- // dependent, if any, get told of our duration even if our
- // duration has already been set, which can happen if we have
- // an explicit end or dur. We should go ahead and add ourself to
- // the parent if we haven't already done so:
- !m_pSourceElement->m_bAddDurationAlreadyDone)
- {
- // /(Note: if endsync="first" causes re-resolving of duration, then
- // it's perfectly valid for bUpdateChildren to be TRUE here.)
- m_bDurationSet = TRUE;
- m_pSourceElement->m_ulDuration = ulDuration;
- if(m_pParent)
- {
- ULONG32 ulDelayFromSyncBaseBegin = 0;
- if (m_pSourceElement->m_bCurBeginIsOffsetFromSyncBase)
- {
- ulDelayFromSyncBaseBegin =
- m_pSourceElement->m_ulBeginOffsetFromSyncBase;
- if (ulDelayFromSyncBaseBegin > 0 &&
- !m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase)
- {
- m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase =
- TRUE; // /=TRUE,not ULONG32. Helps fix PR 68190.
- m_pSourceElement->m_ulDuration += ulDelayFromSyncBaseBegin;
- }
- }
- m_pParent->addDuration(m_pSourceElement->m_ulDuration,
- m_pSourceElement->m_ulDelay,
- ulDelayFromSyncBaseBegin, m_pID);
- m_pSourceElement->m_bAddDurationAlreadyDone = TRUE;
- }
- if(m_pDependent)
- {
- #if defined(XXXEH_WAIT_UNTIL_getCurrentScheduledStopTime_IS_FIXED_WHEN_BEGINOFFSETSET_20011022)
- ULONG32 ulTotalDelay = 0;
- if (HXR_OK !=
- m_pSourceElement->getCurrentScheduledStopTime(ulTotalDelay))
- {
- goto doneSettingDependent;
- }
- #else
- ULONG32 ulTotalDelay = m_pSourceElement->m_ulDelay +
- m_pSourceElement->m_ulDuration;
- // /Helps fix PR 6XXXX(par version): if delay is already packed
- // into the duration, then don't count it twice (as can happen in
- // <seq><par begin="1s">...</par><par begin="1s" ...):
- if (m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase)
- {
- HX_ASSERT(m_pSourceElement->m_ulBeginOffsetFromSyncBase != (UINT32)-1);
- /*OK[]*/ if (m_pSourceElement->m_ulBeginOffsetFromSyncBase != (UINT32)-1)
- {
- HX_ASSERT(m_pSourceElement->m_ulBeginOffsetFromSyncBase <
- ulTotalDelay);
- if (m_pSourceElement->m_ulBeginOffsetFromSyncBase <
- ulTotalDelay)
- {
- ulTotalDelay -=
- m_pSourceElement->m_ulBeginOffsetFromSyncBase;
- }
- }
- }
- #endif
- if (WAY_IN_THE_FUTURE < ulTotalDelay)
- {
- ulTotalDelay = WAY_IN_THE_FUTURE; // /For PR 59584 (par2).
- }
- // /helps fix PR 62688 (case2) where outer seq has media after
- // par w/endsync="all": don't adjustDep.Dur. if delay is indef.:
- if ((m_pDependent->getDelay() != (UINT32)-1 &&
- m_pDependent->getDelay() >= WAY_IN_THE_FUTURE) ||
- // /Helps fix PR 59584 (parFollowsPar version): also don't
- // adjustDep.Dur. if we're about to set the delay to indef
- (m_pDependent->getDelay() == (UINT32)-1 &&
- WAY_IN_THE_FUTURE == ulTotalDelay) )
- {
- HX_ASSERT(ulTotalDelay==WAY_IN_THE_FUTURE && "send content to ehodge");
- }
- else
- {
- adjustDependentDuration(m_pDependent);
- }
- #if defined(_DEBUG) && defined(XXXEH_DEBUGOUT_ADDDURATION)
- {
- FILE* f1 = ::fopen("c:\smil2AddDuration.txt", bFirstTimeAddDurDebugout?
- ADDDURATION_DEBUGOUT_STR_NEW_FILE :
- ADDDURATION_DEBUGOUT_STR_APPEND_TO_FILE );
- ::fprintf(f1, "nt%s:CSmilTimelineElement::parExclDurationResolved();tsetting dependent (%s)'s delay to %lun",
- (const char*)m_pID, (const char*)m_pDependent->m_pID, ulTotalDelay);
- ::fclose(f1);
- bFirstTimeAddDurDebugout = FALSE;
- }
- #endif
- // /XXXEH- TODO: figure out if we need to claim this is being set
- // by "parent" (which is really time base) so clip-begin-like
- // action can occur; I don't think so, however:
- m_pDependent->setDelay(ulTotalDelay, FALSE);
- }
- #if defined(XXXEH_WAIT_UNTIL_getCurrentScheduledStopTime_IS_FIXED_WHEN_BEGINOFFSETSET_20011022)
- doneSettingDependent:
- #endif
- if(bUpdateChildren)
- {
- UINT32 ulNumChildrenDursSet = 0;
- CHXSimpleList::Iterator i = m_pChildren->Begin();
- for(; i != m_pChildren->End(); ++i)
- {
- CSmilTimelineElement* pElement = (CSmilTimelineElement*)(*i);
- // /If child has no resolved, scheduled begin time yet, then
- // for crying out loud don't set its duration yet. This is
- // needed in the case where *this has endsync="all":
- if (SMILEventSourceAll !=
- m_pSourceElement->m_nEndsyncEventSourceTag ||
- pElement->m_pSourceElement->m_bInsertedIntoTimeline)
- {
- ulNumChildrenDursSet++;
- // /Don't set the child's duration unless the new duration
- // is less than the child's existing duration; the SMIL
- // spec says that a parent element can not extend the
- // duration of a child; fixes PR 50572:
- if (pElement->m_pSourceElement && ( (UINT32)-1 ==
- pElement->m_pSourceElement->m_ulDuration ||
- pElement->m_pSourceElement->m_ulDuration >
- m_pSourceElement->m_ulDuration) )
- {
- pElement->setDuration(m_pSourceElement->m_ulDuration,
- TRUE);
- }
- }
- }
- }
- }
- // Check our children's fill behavior
- checkChildrenFillBehavior();
- //[SMIL 1.0 Compliance] Helps fix PR 14420 and 23025:
- // if a source has event-based timing based on this seq's
- // begin time (delay) then we need to notify that source
- // that we've resolved this value:
- m_pParser->m_pTimelineElementManager->notify(m_pID);
- }
- /***************************************************************************/
- /*
- * CSmilTimelinePar methods
- */
- CSmilTimelinePar::CSmilTimelinePar(CSmilElement* pSourceElement,
- CSmilParser* pParser):
- CSmilTimelineElement(pSourceElement, pParser),
- m_nDurationAdded(0),
- m_ulFirstDuration(0),
- m_bFirstDurationHasBeenSet(FALSE),
- m_ulLastDuration(0)
- {
- }
- CSmilTimelinePar::~CSmilTimelinePar()
- {
- }
- void
- CSmilTimelinePar::setDelay(UINT32 ulDelay,
- // /NOTE: we ignore this in time containers that aren't media:
- BOOL bSetByParent)
- {
- #if defined(_DEBUG) && defined(XXXEH_DEBUGOUT_ADDDURATION)
- {
- FILE* f1 = ::fopen("c:\smil2AddDuration.txt", bFirstTimeAddDurDebugout?
- ADDDURATION_DEBUGOUT_STR_NEW_FILE :
- ADDDURATION_DEBUGOUT_STR_APPEND_TO_FILE );
- ::fprintf(f1, "CSmilTimelinePar{%s}::setDelay(delay=%lu, "
- "bSetByParent=%sE) m_bDelaySet=%sE, beginOffset=%lun",
- (const char*)m_pID, ulDelay,
- bSetByParent?"TRU":"FALS",
- m_bDelaySet?"TRU":"FALS", m_pSourceElement->m_lBeginOffset);
- ::fclose(f1);
- bFirstTimeAddDurDebugout = FALSE;
- }
- #endif
- if(m_pSourceElement->m_bBeginOffsetSet)
- {
- m_pSourceElement->m_ulDelay = (
- ((INT32)ulDelay+m_pSourceElement->m_lBeginOffset > 0) ?
- (UINT32)((INT32)ulDelay+m_pSourceElement->m_lBeginOffset):0);
- }
- else
- {
- m_pSourceElement->m_ulDelay = ulDelay;
- }
- if (!m_bDelayEvent) //[SMIL 1.0 compliance] helps fix PR 14420.
- {
- m_bDelaySet = TRUE;
- ULONG32 ulNumChildrenWithNonEventBasedBegins = 0;
- if(m_pChildren)
- {
- CHXSimpleList::Iterator i = m_pChildren->Begin();
- for(; i != m_pChildren->End(); ++i)
- {
- CSmilTimelineElement* pElement = (CSmilTimelineElement*)(*i);
- pElement->setDelay(m_pSourceElement->m_ulDelay, TRUE);
- if (pElement->m_pSourceElement && pElement->m_pSourceElement->
- m_bHasAtLeastOneNonEventBasedBegin)
- {
- ulNumChildrenWithNonEventBasedBegins++;
- }
- }
- }
- // /Fixes PR 24046 (SMIL 2+ par version): if there are no children,
- // then the par's duration is zero, so set it to 0:
- if ((!m_pChildren && m_pSourceElement->m_ulDuration == (UINT32)-1) ||
- 0 == ulNumChildrenWithNonEventBasedBegins)
- {
- // /Checking 1st for explicit end or dur re-fixes PR 57150(par)
- // which was broken by fix for PR 24046 (note: PR 57150 has dur=x
- // *and* endsync="all" which is a strange thing to author):
- if (!m_pSourceElement->m_bHasExplicitDur &&
- !m_pSourceElement->m_bHasExplicitEnd)
- {
- m_pSourceElement->m_ulDuration = 0;
- }
- // /Helps fix PR 62688(par version): if all children are
- // event-begun and there is at least one child, and endsycn="all",
- // then we have an indefinite duration until all child ends resolve:
- if (m_pChildren && SMILEventSourceAll ==
- m_pSourceElement->m_nEndsyncEventSourceTag &&
- // /Ignore endsync if it has explicit end or dur:
- !m_pSourceElement->m_bHasExplicitDur &&
- !m_pSourceElement->m_bHasExplicitEnd)
- {
- m_pSourceElement->m_ulDuration = WAY_IN_THE_FUTURE;
- }
- }
- if (m_pSourceElement->m_ulDuration != (UINT32)-1)
- {
- setDuration(m_pSourceElement->m_ulDuration);
- #if 0 //20011024-0
- // /Fixes PR 61174(version1) and par version of PR 56686
- // (version1): we know our duration already, so let's declare it
- // resolved so we get added to our parent (in case none of our
- // children have scheduled begin times in which case our
- // ::addDuration() would not get called up front and the overall
- // presentation would not include our duration at first):
- if (m_pSourceElement->m_bHasExplicitDur ||
- m_pSourceElement->m_bHasExplicitEnd ||
- // /For PR 62688(par version) and other endsync="all" bugs:
- SMILEventSourceAll ==
- m_pSourceElement->m_nEndsyncEventSourceTag)
- {
- // /Be sure not to override a shorter duration that may have
- // been imposed on us by our parent:
- if (!m_bDurationSet ||
- !m_pSourceElement->m_bAddDurationAlreadyDone)
- {
- HX_ASSERT((UINT32)-1 != m_pSourceElement->m_ulDelay);
- durationResolved(m_pSourceElement->m_ulDuration, FALSE);
- }
- HX_ASSERT(m_bDurationSet && m_pSourceElement->m_bAddDurationAlreadyDone);
- }
- #else /* At least fix it for endsync="all":*/
- // /Fixes PR 61174(version1) and par version of PR 56686
- // (version1): we know our duration already, so let's declare it
- // resolved so we get added to our parent (in case none of our
- // children have scheduled begin times in which case our
- // ::addDuration() would not get called up front and the overall
- // presentation would not include our duration at first):
- if ((!m_pSourceElement->m_bHasExplicitDur &&
- !m_pSourceElement->m_bHasExplicitEnd) &&
- // /For PR 62688(par version) and other endsync="all" bugs:
- SMILEventSourceAll ==
- m_pSourceElement->m_nEndsyncEventSourceTag)
- {
- // /Be sure not to override a shorter duration that may have
- // been imposed on us by our parent:
- if (!m_bDurationSet ||
- !m_pSourceElement->m_bAddDurationAlreadyDone)
- {
- HX_ASSERT((UINT32)-1 != m_pSourceElement->m_ulDelay);
- HX_ASSERT(m_pSourceElement->m_ulDuration ==
- m_pSourceElement->getPureDuration());
- durationResolved(m_pSourceElement->m_ulDuration, FALSE);
- }
- HX_ASSERT(m_bDurationSet && m_pSourceElement->m_bAddDurationAlreadyDone);
- }
- #endif
- }
- }
- else //[SMIL 1.0 compliance] for PR 14420:
- // let's not claim that the delay is set when we still
- // are awaiting a delay (begin) event; we *do* need to
- // add the delay of this to the event's begin offset.
- // This is done by setting the new "m_bNonEventDelaySet"
- // variable to TRUE and leaving m_bDelaySet to FALSE
- // until the ElementResolved() call sets it to true:
- {
- //Parent calls setDelay before we get to ElementResolved,
- // thus m_bDelaySet should never be TRUE if we have a
- // delay event:
- HX_ASSERT(!m_bDelaySet);
- m_bNonEventDelaySet = TRUE; //ElementResolved will look at this.
- m_ulNonEventDelay = ulDelay;
- }
-
- if(m_pDependent && m_bDurationSet)
- {
- adjustDependentDuration(m_pDependent);
- #if defined(XXXEH_WAIT_UNTIL_getCurrentScheduledStopTime_IS_FIXED_WHEN_BEGINOFFSETSET_20011022)
- ULONG32 ulTotalDelay = 0;
- if (HXR_OK !=
- m_pSourceElement->getCurrentScheduledStopTime(ulTotalDelay))
- {
- goto doneSettingDependent;
- }
- #else
- ULONG32 ulTotalDelay = m_pSourceElement->m_ulDelay +
- m_pSourceElement->m_ulDuration;
- // /Helps fix PR 6XXXX(par version): if delay is already packed
- // into the duration, then don't count it twice (as can happen in
- // <seq><par begin="1s">...</par><par begin="1s" ...):
- if (m_pSourceElement->m_bDurationIncludesDelayBeyondSyncbase)
- {
- HX_ASSERT(m_pSourceElement->m_ulBeginOffsetFromSyncBase != (UINT32)-1);
- /*OK[]*/ if (m_pSourceElement->m_ulBeginOffsetFromSyncBase !=(UINT32)-1)
- {
- HX_ASSERT(m_pSourceElement->m_ulBeginOffsetFromSyncBase <
- ulTotalDelay);
- if (m_pSourceElement->m_ulBeginOffsetFromSyncBase <
- ulTotalDelay)
- {
- ulTotalDelay -=
- m_pSourceElement->m_ulBeginOffsetFromSyncBase;
- }
- }
- }
- #endif
- if (WAY_IN_THE_FUTURE < ulTotalDelay)
- {
- HX_ASSERT(WAY_IN_THE_FUTURE == ulTotalDelay && "PR 59584");
- ulTotalDelay = WAY_IN_THE_FUTURE; // /For PR 59584.
- }
- #if defined(_DEBUG) && defined(XXXEH_DEBUGOUT_ADDDURATION)
- {
- FILE* f1 = ::fopen("c:\smil2AddDuration.txt", bFirstTimeAddDurDebugout?
- ADDDURATION_DEBUGOUT_STR_NEW_FILE :
- ADDDURATION_DEBUGOUT_STR_APPEND_TO_FILE );
- ::fprintf(f1, "nt%s:CSmilTimelinePar::setDelay(%lu): to %lu;"
- "tsetting dependent (%s)'s delay to %lun", (const char*)m_pID,
- ulDelay, m_pSourceElement->m_ulDelay,
- (const char*)m_pDependent->m_pID, ulTotalDelay);
- ::fclose(f1);
- bFirstTimeAddDurDebugout = FALSE;
- }
- #endif
-
- // /XXXEH- TODO: figure out if we need to claim this is being set by
- // "parent" (which is really time base) so clip-begin-like action can
- // occur; I don't think so, however:
- m_pDependent->setDelay(ulTotalDelay, FALSE);
- }
- #if defined(XXXEH_WAIT_UNTIL_getCurrentScheduledStopTime_IS_FIXED_WHEN_BEGINOFFSETSET_20011022)
- doneSettingDependent:
- #endif
- //[SMIL 1.0 comliance] Helps fix PR 14420 and 23025:
- m_pParser->m_pTimelineElementManager->notify(m_pID);
- }
- void
- CSmilTimelinePar::setDuration(UINT32 ulDuration, BOOL bSetFromParent,
- BOOL bDurationExtendingDueToPause)
- {
- if (bDurationExtendingDueToPause)
- {
- // /Need to handle this case:
- HX_ASSERT(!bDurationExtendingDueToPause);
- }
- setParExclDuration(ulDuration, bSetFromParent);
- }
- void
- CSmilTimelinePar::setMaxDuration(UINT32 ulMaxDuration)
- {
- setParExclMaxDuration(ulMaxDuration);
- }
- void
- CSmilTimelinePar::resetDelay(UINT32 ulDelay)
- {
- INT32 lAdjustedDelay = 0;
- UINT32 ulPriorDelay = m_pSourceElement->m_ulDelay;
- if(m_pSourceElement->m_bBeginOffsetSet)
- {
- lAdjustedDelay = (INT32)ulDelay + m_pSourceElement->m_lBeginOffset;
- m_pSourceElement->m_ulDelay = lAdjustedDelay > 0?lAdjustedDelay:0;
- }
- else
- {
- m_pSourceElement->m_ulDelay = ulDelay;
- }
- if(m_pChildren)
- {
- CHXSimpleList::Iterator i = m_pChildren->Begin();
- for(; i != m_pChildren->End(); ++i)
- {
- CSmilTimelineElement* pElement = (CSmilTimelineElement*)(*i);
- pElement->resetDelay(m_pSourceElement->m_ulDelay);
- }
- }
- // /To fix PR 59851, we need to update our next-in-seq (m_pDependent) as
- // well as make sure sync-arc listeners know we've changed our overall
- // time bounds delay as well;
- if (m_pDependent && m_bDurationSet &&
- ulPriorDelay != m_pSourceElement->m_ulDelay)
- {
- #if defined(XXXEH_WAIT_UNTIL_getCurrentScheduledStopTime_IS_FIXED_WHEN_BEGINOFFSETSET_20011022)
- ULONG32 ulTotalDelay = 0;
- if (m_pSourceElement->m_bCurBeginIsOffsetFromSyncBase &&