smlelem.cpp

来自「symbian 下的helix player源代码」· C++ 代码 · 共 2,248 行 · 第 1/5 页

CPP
2,248
字号
/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: smlelem.cpp,v 1.5.12.1 2004/07/09 01:58:01 hubbe 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 "ihxpckts.h"
#include "hxxml.h"
#include "smiltype.h"
// pncont
#include "hxstring.h"
#include "hxslist.h"
#include "hxstack.h"
#include "chxpckts.h"
// pnmisc
#include "nptime.h"
#include "smpte.h"
#include "hxwinver.h"
#include "hxstrutl.h"  /* for new_string(). */
// rnxmllib
#include "hxxmlprs.h"
// rmasmil
#include "smlparse.h"
#include "smltime.h"
#include "smlprstime.h"
#include "animattr.h"
#include "smlelem.h"
// pndebug
#include "hxheap.h"
#ifdef _DEBUG
#undef HX_THIS_FILE		
static const char HX_THIS_FILE[] = __FILE__;
#endif
 
/*
 * CSmilElement methods
 */

CSmilElement::CSmilElement(SMILNode* pNode):
    m_pNode(pNode),
    m_lBeginOffset(0),
    m_bBeginOffsetSet(FALSE),
    m_bNegBeginOffsetAlreadyUsed(FALSE),
    m_bCurBeginIsOffsetFromSyncBase(FALSE),
    m_ulBeginOffsetFromSyncBase((UINT32)-1),
    m_ulClipBegin((UINT32)-1),
    m_ulAuthoredClipBegin((UINT32)-1),
    m_ulClipEnd((UINT32)-1),
    m_ulDelay((UINT32)-1),
    m_ulDuration((UINT32)-1),
    m_ulOriginalDuration((UINT32)-1),
    m_ulDurationInAddTrack((UINT32)-1),
    m_bCurEndClippedByParent(FALSE),
    m_ulMaxDuration((UINT32)-1),
    m_ulMaxActiveDur((UINT32)-1),
    m_ulMinActiveDur(0),
    m_ulAuthoredDur((UINT32)-1),
    m_bHasExplicitDur(FALSE),
    m_bHasExplicitEnd(FALSE),
    m_bDurationIncludesDelayBeyondSyncbase(FALSE),
    m_bAddDurationAlreadyDone(FALSE),
    m_bUseMediaDurForMinDur(FALSE),
    m_bUseMediaDurForMaxDur(FALSE),
    m_lEndOffset(0),
    m_bEndOffsetSet(FALSE),
    m_ulAnticipatedPauseDur(0),
    m_ulEndSync((UINT32)-1),
    m_fRepeatValue(1.0),
    m_ulTimestamp(0),
    m_bInsertedIntoTimeline(FALSE),
    m_bHasBeenScheduled(FALSE),
    m_bIsPausedInExcl(FALSE),
    m_bIsDeferredInExcl(FALSE),
    m_ulTimeDeferralOccurred((UINT32)-1),
    m_bIsStoppedInExcl(FALSE),
    m_ulStopTimeInExcl((UINT32)-1),
    m_bCurrentSourceIsLive(FALSE),
    m_bRendererInitialized(FALSE),
    m_bIsRestarting(FALSE),
    m_bAwaitingSyncAncestorBeginNotification(FALSE),
    m_ulLongSyncArcBeginInGroupTime((UINT32)-1),
    m_bIndefiniteDuration(FALSE),
    m_bIndefiniteEnd(FALSE),
    m_bIndefiniteBegin(FALSE),
    m_restartBehavior(SmilRestartAlways),
    m_restartDefaultBehavior(SmilRestartInherit),
    // /Defaults to "default" which means use val of syncToleranceDefault:
    m_ulSyncTolerance((UINT32)-1),
    // /Defaults to "inherit"; if there is no parent timed element, then
    // it is implementation-dependent (but should be less than or = 2s):
    m_ulSyncToleranceDefault((UINT32)-1),
    m_syncBehavior(SmilSyncBehaviorDefault),
    m_syncBehaviorDefault(SmilSyncBehaviorInherit),
    m_ulReadIndex(0),
    m_nBeginEventSourceTag(SMILEventSourceNone),
    m_nEndEventSourceTag(SMILEventSourceNone),
    m_nEndsyncEventSourceTag(SMILEventSourceNone),
    m_lBeginEventClockValue(0),
    m_lEndEventClockValue(0),
    m_pHandler(0),
    m_pTimelineElement(NULL),
    m_pBeginTimeList(NULL),
    m_pEndTimeList(NULL),
    m_bWallClockBegin(FALSE),
    m_bWallClockEnd(FALSE),
    m_bHasAtLeastOneEventBasedBegin(FALSE),
    m_bHasAtLeastOneNonEventBasedBegin(FALSE),
    m_eFill(FillDefault),
    m_eFillDefault(FillDefaultInherit),
    m_eActualFill(FillDefault),
    m_eErase(EraseWhenDone),
    m_ulRemoveTime(((UINT32) -1)),
    m_bUsesExternalMediaMarkerFile(FALSE),
    m_bClipBeginUsesMarker(FALSE),
    m_bClipBeginMarkerResolved(FALSE),
    m_bWaitingOnClipBeginToResolve(FALSE),
    m_pszClipBeginMarkerName(NULL),
    m_pszClipBeginExternalMarkerFileName(NULL),
    m_bClipEndUsesMarker(FALSE),
    m_bClipEndMarkerResolved(FALSE),
    m_bWaitingOnClipEndToResolve(FALSE),
    m_pszClipEndMarkerName(NULL),
    m_pszClipEndExternalMarkerFileName(NULL),
    m_eAccessErrorBehavior(AccessErrorBehaviorInherit)
{
    // /XXXEH- we may need to set m_bIndefiniteBegin to TRUE if
    // hasAncestor(SMILExcl, this), but setInitialDelay() fix seems to be
    // all we need (...<==famous last words).
    m_pHyperlinks = new CHXSimpleList;
    getParentRestartDefault();
}

CSmilElement::~CSmilElement()
{
    if (m_pBeginTimeList)
    {
	CHXSimpleList::Iterator ndx = m_pBeginTimeList->Begin();
	for (; ndx != m_pBeginTimeList->End(); ++ndx)
	{
	    SmilTimeValue* pTV = (SmilTimeValue*)(*ndx);
	    HX_DELETE(pTV);
	}
	HX_DELETE(m_pBeginTimeList);
    }
    if (m_pEndTimeList)
    {
	CHXSimpleList::Iterator ndx = m_pEndTimeList->Begin();
	for (; ndx != m_pEndTimeList->End(); ++ndx)
	{
	    SmilTimeValue* pTV = (SmilTimeValue*)(*ndx);
	    HX_DELETE(pTV);
	}
	HX_DELETE(m_pEndTimeList);
    }


    HX_DELETE(m_pHyperlinks);
    HX_DELETE(m_pTimelineElement);
    HX_VECTOR_DELETE(m_pszClipBeginMarkerName);
    HX_VECTOR_DELETE(m_pszClipBeginExternalMarkerFileName);
    HX_VECTOR_DELETE(m_pszClipEndMarkerName);
    HX_VECTOR_DELETE(m_pszClipEndExternalMarkerFileName);
}

void
CSmilElement::addDuration(UINT32 ulDuration)
{
    // default add duration just attempts to add it to it's parent
    m_ulDuration = ulDuration;
    if(m_pNode->m_pParent && m_pNode->m_pParent->m_pElement)
    {
	m_pNode->m_pParent->m_pElement->addDuration(m_ulDuration);
	m_bAddDurationAlreadyDone = TRUE;
    }
}

void
CSmilElement::addElement(CSmilElement* pElement,
    UINT32& ulBeginOffset, UINT32& ulDuration)
{
}


void
CSmilElement::prepForRestart(BOOL bParentIsRestarting, LONG32 lWhen)
{
    m_bInsertedIntoTimeline = FALSE;
    m_bRendererInitialized = FALSE;
    m_bBeginOffsetSet = FALSE;
    // /Reset these, too, or hiding of site will happen too early next time:
    m_bCurBeginIsOffsetFromSyncBase = TRUE;
    // /This seems to work fine in case where begin="x; y" where x is a
    // clock value and y is an event-arc that resolves at/to a time prior
    // to x.  (The other option is to set m_bCurBeginIsOffsetFromSyncBase
    // to FALSE when !m_bBeginOffsetSet):
    m_ulBeginOffsetFromSyncBase = 0;

    m_bNegBeginOffsetAlreadyUsed = FALSE;

    m_ulClipBegin = m_ulAuthoredClipBegin;

    m_bAddDurationAlreadyDone = FALSE;


    // /XXXEH- TODO: test this!:
    m_bDurationIncludesDelayBeyondSyncbase = FALSE;

    m_bIsPausedInExcl = FALSE;
    m_bIsDeferredInExcl = FALSE;
    m_ulTimeDeferralOccurred = (UINT32)-1;
    m_bIsStoppedInExcl = FALSE;
    m_ulAnticipatedPauseDur = 0;

    // /If we restart a source, the next play may be a different file, even
    // live one time and on-demand the next, so reset this and let next call
    // to TrackDurationSet() tell us if it's live this time:
    m_bCurrentSourceIsLive = FALSE;

    // /Adding this helps fix a lot of restart problems, including part of
    // PR 62408 and par version of PR 50660.  The playToAssoc was never
    // removed when the track ended the first time, so the doc renderer
    // (m_pHandler) used to see this track as already added and would
    // erroneously add this restart as a repeat track:
    m_bIsRestarting = TRUE;

    // /Helps fix restart problems related to PR 55253:
    if (bParentIsRestarting)
    {
	LONG32 lNextResolvedEndTime = 0;
	BOOL bHasFutureResolvedEnd = FALSE;
	if (m_bHasExplicitEnd)
	{
	    SmilTimeValue* pNextResolvedEndTimeValue = NULL;
	    HX_RESULT rettimeval = HXR_OK;
	    // /lWhen must be in syncBase time space, not group time space:
	    rettimeval = getNextResolvedTimeValue(pNextResolvedEndTimeValue,
		    SMILTIME_NEGATIVE_INFINITY, lWhen, SmilEndTimeList, NULL);

	    if (SUCCEEDED(rettimeval)  &&  NULL != pNextResolvedEndTimeValue)
	    {
		HX_RESULT rtval = pNextResolvedEndTimeValue->
			getEffectiveResolvedTime(lNextResolvedEndTime);
		if (SUCCEEDED(rtval))
		{
		    bHasFutureResolvedEnd = TRUE;
		    if (lWhen < lNextResolvedEndTime)
		    {
			m_ulDuration = (UINT32)(lNextResolvedEndTime - lWhen);
		    }
		}
	    }
	}
	if (m_bHasExplicitDur)
	{
	    if (!bHasFutureResolvedEnd)
	    {
		m_ulDuration = m_ulAuthoredDur;
	    }
	    else if (lNextResolvedEndTime - lWhen > (LONG32)m_ulAuthoredDur)
	    {
		m_ulDuration = m_ulAuthoredDur;
	    }
	}
	else
	{
	    // /Let SetDelay() and insertTimeline... deal with new duration:
	    m_ulDuration = (UINT32)-1;
	}
    }

    // /Reset the delay since it will be new, obviously, for this restart;
    // helps fix restart problems related to PR 56233:
    m_ulDelay = (UINT32)-1;

    // /Note: we don't want to or need to reset the delay here.  A restart
    // based on either a syncArc or eventArc will take care of that.

    if (m_pTimelineElement)
    {
	m_pTimelineElement->prepForRestart();
    }

    // /Now, call this function for all descendants as well in case this is
    // a time container (or a media object with timeline-element children);
    // (Helps fix restart problems related to PR 55253)
    SMILNode* pChild = m_pNode->getFirstChild();
    while (pChild)
    {
	CSmilElement* pElement = pChild->m_pElement;
	if (pElement  &&  pElement->m_pHandler  &&
		pElement->m_bInsertedIntoTimeline)
	{
	    pElement->prepForRestart(TRUE, lWhen);
	}
	pChild = m_pNode->getNextChild();
    }
}


void
CSmilElement::prepForPauseInExcl(LONG32 lCurTime)
{
    m_bIsPausedInExcl = TRUE;

    // /If we're being set to paused state, then we need to adjust our hide
    // event (removeTime) in concert with adjusting when we will end:
    BOOL bHasFutureResolvedExplicitEnd = FALSE;

    if (m_bHasExplicitEnd)
    {
	SmilTimeValue* pNextResolvedEndTimeValue = NULL;
	HX_RESULT rettimeval = HXR_OK;
	// /lCurTime must be in syncBase time space, not group time space:
	rettimeval = getNextResolvedTimeValue(pNextResolvedEndTimeValue,
		SMILTIME_NEGATIVE_INFINITY, lCurTime, SmilEndTimeList, NULL);

	if (SUCCEEDED(rettimeval)  &&  NULL != pNextResolvedEndTimeValue)
	{
	    LONG32 lNextResolvedEndTime = SMILTIME_NEGATIVE_INFINITY;
	    HX_RESULT rtval = pNextResolvedEndTimeValue->
		    getEffectiveResolvedTime(lNextResolvedEndTime);
	    if (SUCCEEDED(rtval))
	    {
		HX_ASSERT(lCurTime <= lNextResolvedEndTime);
		bHasFutureResolvedExplicitEnd = TRUE;
		updateRemoveTime(lNextResolvedEndTime);
	    }
	}
    }

    // /If we don't have explicit end, then we'll end when we get resumed
    // plus the remainder of our duration:
    if (!bHasFutureResolvedExplicitEnd)
    {
	updateRemoveTime(SMILTIME_PAUSED_INDEFINITELY);
    }
}

void
CSmilElement::prepForResumeInExcl()
{
    HX_ASSERT(m_bIsPausedInExcl);

    LISTPOSITION lPos = NULL;
    HX_ASSERT(m_pBeginTimeList);
    if (m_pBeginTimeList)
    {
	lPos = m_pBeginTimeList->GetHeadPosition();
    }
    while (lPos)
    {
	SmilTimeValue* pTimeVal =
		(SmilTimeValue*)m_pBeginTimeList->GetAt(lPos);

	// /There should be only one resumeEvent:
	if (pTimeVal  &&  pTimeVal->isResumeEvent())
	{
	    // /Fixes PR 62408: remove resumeEvent from element's begin
	    // list since it was an internally-generated single-use begin
	    // value and we don't want it to re-resolve when (if) the
	    // original pausing element restarts and then raises another
	    // resumeEvent when it ends again:
	    m_pBeginTimeList->RemoveAt(lPos);
	    break;
	}
    	m_pBeginTimeList->GetNext(lPos);
    }

    m_bIsPausedInExcl = FALSE;
}

void
CSmilElement::prepForStopInExcl(LONG32 lCurTime)
{
    m_bIsStoppedInExcl = TRUE;
    m_ulStopTimeInExcl = (ULONG32)lCurTime;
}

void
CSmilElement::prepForDeferralInExcl(UINT32 lCurTime)
{
    m_ulTimeDeferralOccurred = lCurTime;
    m_bIsDeferredInExcl = TRUE;
}



HX_RESULT
CSmilElement::setBeginTime(CSmilParser* pParser)
{
    HX_RESULT ret = HXR_OK;
 
    BOOL bBeginTimeHasBeenSet = FALSE;

    UINT32 ulOffset = 0;
    SmilTimeValue* pNextResolvedTimeValue = NULL;

    LISTPOSITION lPos = NULL;

    // /We need this so we can go through
    CHXSimpleList* pListOfAllResolvedBeginTimes = new CHXSimpleList;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?