⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smlparse.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    }

#else
    // Don't QI core for IID_IHXXMLParser; use our own instance.
    HXXMLParser* parser = new HXXMLParser();

    if (parser)
    {
	parser->AddRef();
    }
    else
    {
	rc = HXR_OUTOFMEMORY;
    }
    
    if (SUCCEEDED(rc))
    {
	m_pResponse = new CSmil1ParserResponse(this);
	m_pResponse->AddRef();
	rc = parser->Init(m_pResponse, NULL, TRUE);	// strict parser
    }
    if (m_bStoreErrors && parser)
    {
	parser->InitErrorNotifier(m_pResponse);
    }
    m_pParser = (IHXXMLParser*)parser;


#endif	
    
    return rc;
}

HX_RESULT
CSmil1Parser::parse(IHXBuffer* pBuffer, BOOL bIsFinal)
{
    HX_RESULT rc = HXR_OK;

    rc = m_pParser->Parse(pBuffer, bIsFinal);
    if(HXR_OK != rc)
    {
	m_pParser->GetCurrentLineNumber(m_ulErrorLineNumber);
	m_pParser->GetCurrentColumnNumber(m_ulErrorColumnNumber);
	HX_RELEASE(m_pErrorText);
	m_pParser->GetCurrentErrorText(m_pErrorText);
    }
    return rc;
}

HX_RESULT
CSmil1Parser::durationResolved(const char* pID, UINT32 ulDuration)
{
    SMIL1Node*	pNode = NULL;
    IHXBuffer* pBuf = NULL;

    if(m_pIDMap->Lookup(pID, (void*&)pNode))
    {	
	if (pNode->m_pElement->m_bIndefiniteDuration)
	{
	    goto cleanup;
	}
	
	// add duration to parent element
	if(pNode &&
	   pNode->m_pElement &&
	   pNode->m_pElement->m_pTimelineElement)
	{
	    pNode->m_pElement->m_pTimelineElement->setDuration(ulDuration);
	}
    }

cleanup:

    HX_RELEASE(pBuf);

    return HXR_OK;
}

BOOL AncestorEventsAreResolved(SMIL1Node* pNode)
{
    if (!pNode  ||  !pNode->m_pElement  ||
	    !pNode->m_pElement->m_pTimelineElement  ||  pNode->m_tag == SMILBody)
    {
	return TRUE;
    }
    //Now, look to see if its duration and delay events, if any, are
    // resolved:
    if ( ( (pNode->m_pElement->m_pTimelineElement->durationEvent()  &&
	!pNode->m_pElement->m_pTimelineElement->durationSet())  ||
	(pNode->m_pElement->m_pTimelineElement->delayEvent()  &&
	!pNode->m_pElement->m_pTimelineElement->initialDelaySet()) )  &&
	//[SMIL 1.0 compliance] Helps fix PR 32578:
	//However, if we have a duration event and it's based on a child's
	// timing (as can happen via endsync="id(child)", then we want to
	// avoid this element waiting for its parent to be resolved while
	// the parent is waiting for this element to be resolved:
	(!pNode->m_pElement->m_pTimelineElement->durationEvent()  ||
	SMILEventSourceID != pNode->m_pElement->m_nEndsyncEventSourceTag) )
    {
	return FALSE; //We still need to await event resolution.
    }
    //pNode is ok but its dependency ancestors may still be unresolved and
    // thus pNode may still have timing constraints from its dependency
    // ancestors due to their unresolved event(s):
    return AncestorEventsAreResolved(pNode->m_pParent);
}

void
CSmil1Parser::insertTimelineElement(const char* pID, UINT32 ulDelay)
{
    SMIL1Node* pNode = 0;
    if(m_pIDMap->Lookup(pID, (void*&)pNode))
    {
	if(pNode &&
	    pNode->m_pElement &&
	    !pNode->m_pElement->m_bInsertedIntoTimeline  &&
	    //[SMIL 1.0 compliance] Helps fix PR 16629:
	    // We don't want to insert a node into the timeline if
	    // its begin or end is dependent on another (not-yet-
	    // resolved) element:
	    ( (!pNode->m_pElement->m_pTimelineElement->durationEvent()  ||
	    pNode->m_pElement->m_pTimelineElement->durationSet())  &&
	    (!pNode->m_pElement->m_pTimelineElement->delayEvent()  ||
	    pNode->m_pElement->m_pTimelineElement->initialDelaySet()) )
	    //[SMIL 1.0 compliance] Helps fix 14420:
	    // First, we need to look all the way up the tree of ancestors
	    // to see if any of them have event-based delays or durations
	    // and to make sure the appropriate time(s) are resolved.  If
	    // not, we'll have to await those event resolutions before
	    // inserting this element into the timeline:
	    &&  AncestorEventsAreResolved(pNode)
	    )
	{
	    // /[SMIL 1.0 Compliance] Fixes PR 27644:
	    // if our begin offset is same or greater than our parent's
	    // end offset, then we should be ignored:
	    if ( pNode->m_pParent  &&  pNode->m_pParent->m_pElement  &&
		    pNode->m_pElement->m_ulBeginOffset != ((UINT32)-1)  &&
		    pNode->m_pParent->m_pElement->m_ulEndOffset != 
		    ((UINT32)-1)  &&
		    (pNode->m_pElement->m_ulBeginOffset >
		    pNode->m_pParent->m_pElement->m_ulEndOffset) )
	    {
		return; //Don't insert this because it can't ever play.
	    }

	    // skip the element if its duration == 0
	    if (0 == pNode->m_pElement->m_ulDuration)
	    {
		durationResolved(pNode->m_id, 0);
	    }
	    else
	    {
		pNode->m_pElement->m_ulDelay = ulDelay;
		pNode->m_pElement->m_ulTimestamp = INITIAL_STREAM1_TIMESTAMP;
		pNode->m_pElement->m_bInsertedIntoTimeline = TRUE;
		insertElementByTimestamp(pNode->m_pElement);
	    }
	}
    }
}

void
CSmil1Parser::resetTimelineElementDuration(const char* pID, 
					  UINT32 ulDuration)
{
    SMIL1Node* pNode = NULL;
    if(m_pIDMap->Lookup(pID, (void*&)pNode))
    {
	CSmil1SourceUpdate* pUpdate = new CSmil1SourceUpdate;
	pUpdate->m_ulTimestamp = INITIAL_STREAM1_TIMESTAMP;
	pUpdate->m_srcID = pID;
	pUpdate->m_ulUpdatedDuration = ulDuration;

	if(!m_pSourceUpdateList)
	{
	    m_pSourceUpdateList = new CHXSimpleList;
	}
	m_pSourceUpdateList->AddTail(pUpdate);
	insertElementByTimestamp(pUpdate);
    }
}

CSmil1Element*
CSmil1Parser::findElement(const char* pID)
{
    SMIL1Node* pNode = NULL;
    if(m_pIDMap->Lookup(pID, (void*&)pNode))
    {
	return pNode->m_pElement;
    }
    return NULL;
}

const char*
CSmil1Parser::assignID(const char* pPrefix)
{
    SafeSprintf(m_pVarName, 256, "%s_%ld", pPrefix, GetUniqueNumber());
    return m_pVarName;
}

UINT16
CSmil1Parser::getFragmentGroup(const char* pFragment)
{
    if(pFragment)
    {
	SMIL1Node* pNode = 0;
	if(m_pIDMap->Lookup(pFragment, (void*&)pNode))
	{
	    if(!pNode->m_bDelete)
	    {
		if(pNode->m_tag == SMILAAnchor ||
		    pNode->m_tag == SMILSwitch)
		{
		    SMIL1Node* pChildNode = getTimelineDescendent(pNode, NULL);
		    while(pChildNode)
		    {
			if(!pChildNode->m_bDelete)
			{
			    return pChildNode->m_nGroup;
			}
			pChildNode = getTimelineDescendent(pNode, pChildNode);
		    }
		}
		else if(pNode->m_tag == SMILAnchor)
		{
		    SMIL1Node* pParentNode = pNode->m_pParent;
		    if(pParentNode &&
			!pParentNode->m_bDelete)
		    {
			return pParentNode->m_nGroup;
		    }
		}
		else
		{
		    return pNode->m_nGroup;
		}
	    }
	}
    }
    return 0;
}

UINT32
CSmil1Parser::getFragmentOffset(const char* pFragment,
	//This BOOL will be set to FALSE if the fragment
	// does not exist or does not yet have a resolved
	// begin time.  This was necessary to fix PR 22655:
	BOOL& bFragFoundAndResolved)
{
    bFragFoundAndResolved = FALSE;
    if(pFragment)
    {
	UINT32 ulAnchorBegin = 0;
	SMIL1Node* pNode = NULL;
	CSmil1Element* pElement = NULL;
	CSmil1Element* pActualElement = NULL;
	if(m_pIDMap->Lookup(pFragment, (void*&)pNode) &&
	    pNode->m_pElement)
	{
	    pElement = pNode->m_pElement;
	    if(pNode->m_tag == SMILSwitch ||
		pNode->m_tag == SMILAAnchor)
	    {
		SMIL1Node* pChildNode = getTimelineDescendent(
		    pNode, NULL);
		while(pChildNode)
		{
		    if(!pChildNode->m_bDelete)
		    {
			pActualElement = pChildNode->m_pElement;
			break;
		    }
		    pChildNode = getTimelineDescendent(
			pNode, pChildNode);
		}
	    }
	    else if(pNode->m_tag == SMILAnchor)
	    {
		if(pElement->m_ulBeginOffset != (UINT32)-1)
		{
		    ulAnchorBegin = pElement->m_ulBeginOffset;
		}
		SMIL1Node* pParent = pNode->m_pParent;
		if(pParent)
		{
		    pActualElement = pParent->m_pElement;
		}
	    }
	    else
	    {
		pActualElement = pElement;
	    }

	    if(pActualElement)
	    {
		//[SMIL 1.0 Compliance] Fixes PR 26464:
		// Use delay (which already includes begin offset)
		// if it's a valid value, else use begin offset
		// without delay added (see comment below):
		if(pActualElement->m_ulDelay != (UINT32)-1)
		{
		    bFragFoundAndResolved = TRUE;
		    return pActualElement->m_ulDelay +
			ulAnchorBegin;
		}
		else if(pActualElement->m_ulBeginOffset != (UINT32)-1)
		{ 
		    bFragFoundAndResolved = TRUE; 
		    //Changed this while fixing PR 26464:
		    // This used to return pActualElement->m_ulDelay +
		    // pActualElement->m_ulBeginOffset + ulAnchorBegin but
		    // the delay can already account for the begin if both
		    // are set so we'd end up seeking past where we were
		    // supposed to go by the amount of the begin offset. 
		    // Also, we weren't even checking to see
		    // if delay was valid before using it (and now we're
		    // sure it is invalid per check above): 
		    return pActualElement->m_ulBeginOffset +
			ulAnchorBegin; 
		} 
		else
		{
		    return 0;
		}
	    }
	}
    }
    return 0;
}

SMIL1Node*
CSmil1Parser::findFirstNode(SMIL1NodeList* pNodeList, SMIL1NodeTag tag)
{
    if(!pNodeList)
    {
	return 0;
    }

    SMIL1Node* pFoundNode = 0;
    CHXSimpleList::Iterator i;
    for(i=pNodeList->Begin();i!=pNodeList->End();++i)
    {
	SMIL1Node* pNode = (SMIL1Node*)(*i);
	if(pNode->m_tag == tag)
	{
	    pFoundNode = pNode;
	}
	else
	{
	    pFoundNode = findFirstNode(pNode->m_pNodeList, tag);
	}
	if(pFoundNode)
	{
	    break;
	}
    }
    return pFoundNode;
}

SMIL1Node*
CSmil1Parser::findFirstNode(SMIL1NodeTag tag)
{
    return findFirstNode(m_pNodeList, tag);
}

SMIL1Node*
CSmil1Parser::getFirstNodeChild(SMIL1Node* pNode)
{
    m_pCurNode = pNode;
    if(!m_pCurNode)
    {
	return 0;
    }
   return m_pCurNode->getFirstChild();
}

SMIL1Node*
CSmil1Parser::getNextNodeChild()
{
    if(!m_pCurNode)
    {
	return 0;
    }
    return m_pCurNode->getNextChild();
}

HX_RESULT
CSmil1Parser::parseClockValue(const char* pValue, UINT32& ulTimeValue)
{
    // try npt
    char* pPtr = (char *)strstr(pValue, "npt=");
    if(pPtr)
    {
	pPtr += 4;  // point to beginning of clock value
	//[SMIL 1.0 compliance] fixes PR 26445: if "npt=4h" is specified,
	// we need to convert to "14400s" otherwise the 4 is treated as
	// seconds:
	char* pHourChar = strchr(pPtr, 'h');
	if (pHourChar  &&  !strchr(pPtr, ':')) //then it's hours without ':'
	{
	    IHXBuffer* pBuf = new CHXBuffer;
	    if (pBuf)
	    {
		pBuf->AddRef();

		*pHourChar = '\0'; //get rid of the 'h' in pPtr.
		pBuf->Set((const unsigned char *)pPtr,
		    strlen(pPtr) + strlen(":00:00") + 1);
		char* pTmp = (char*)pBuf->GetBuffer();
		strcat(pTmp, ":00:00"); /* Flawfinder: ignore */
		NPTime clockTime((const char*)pTmp);
		ulTimeValue = (UINT32)clockTime;
		pBuf->Release();
	    }
	    else
	    {
		return HXR_OUTOFMEMORY;
	    }
	}
	//END fix for PR 26445.
	else
	{
	    NPTime clockTime(pPtr);
	    ulTimeValue = (UINT32)clockTime;
	}
	return HXR_OK;
    }
    // try smpte
    pPtr = (char *)strstr(pValue, "smpte=");
    if(pPtr)
    {
	pPtr += 6;  // point to beginning of clock value
	SMPTETimeCode clockTime(pPtr);
	ulTimeValue = (UINT32)clockTime;
	return HXR_OK;
    }
    pPtr = (char *)strstr(pValue, "smpte-30-drop=");
    if(pPtr)
    {
	pPtr += 14;  // point to beginning of clock value
	SMPTETimeCode clockTime(pPtr);
	ulTimeValue = (UINT32)clockTime;
	return HXR_OK;
    }
    pPtr = (char *)strstr(pValue, "smpte-25=");
    if(pPtr)
    {
	pPtr += 9;  // point to beginning of clock value
	SMPTETimeCode clockTime;
        clockTime.m_framesPerSec = SMPTETimeCode::FPS_25;
        clockTime.fromString(pPtr);
	ulTimeValue = (UINT32)clockTime;
	return HXR_OK;
    }
    else if(strchr(pValue, ':'))     // try just hh:mm:ss with no prefix/suffix
    {
	NPTime clockTime(pValue);
	ulTimeValue = (UINT32)clockTime;
	return HXR_OK;
    }

    // ok, try h/min/s/ms

    char* pEndPtr = 0;
    double dVal = strtod(pValue, &pEndPtr);
    if(strcmp(pEndPtr, "h") == 0)
    {
	ulTimeValue = (UINT32)(dVal * 60.0 * 60.0 * 1000.0);
	return HXR_OK;
    }
    else if(strcmp(pEndPtr, "min") == 0)
    {
	ulTimeValue = (UINT32)(dVal * 60.0 * 1000.0);
	return HXR_OK;
    }
    else if(strcmp(pEndPtr, "s") == 0  ||
	    //[SMIL 1.0 compliance] Fixes PR 22673: the SMIL doc says that we
	    // need to default to seconds if no unit-type is given:
	    //     Timecount-val         ::= Timecount ("." Fraction)?
	    //              ("h" | "min" | "s" | "ms")? ; default is "s"
	    (!strlen(pEndPtr)) )
    {
	ulTimeValue = (UINT32)(dVal * 1000.0);
	return HXR_OK;
    }
    else if(strcmp(pEndPtr, "ms") == 0)
    {
	ulTimeValue = (UINT32)(dVal);
	return HXR_OK;
    }
    //else something other than "h", "min", "s", "", or "ms" was specified:
    else
    {
	return HXR_FAIL;
    }
}

HX_RESULT
CSmil1Parser::parseAnchorCoords(const char* pCoords, CSmil1AnchorElement* pAnchor)
{
    HX_RESULT rc = HXR_OK;
    double coordArray[4];
    BOOL percentArray[4];

    int i = 0;
    for(i=0; i<4; ++i)
    {
	coordArray[i] = 0.0;
	percentArray[i] = FALSE;
    }

    char* pCoordCopy = new_string(pCoords);

⌨️ 快捷键说明

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