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