📄 sm1rendr.cpp
字号:
m_pStream = pStream;
m_pStream->AddRef();
m_pPlayer = pPlayer;
m_pPlayer->AddRef();
m_pPlayer->GetClientEngine(m_pEngine);
m_pPlayer->GetClientContext(m_pClientContext);
IHXBuffer* pBuffer = NULL;
IHXPreferences* pPreferences = NULL;
IHXRendererAdviseSink* pRendererAdviseSink = NULL;
if (HXR_OK == m_pPlayer->QueryInterface(IID_IHXPreferences, (void**)&pPreferences))
{
if (HXR_OK == pPreferences->ReadPref("useNestedMeta", pBuffer))
{
m_bUseNestedMeta = atoi((const char*)pBuffer->GetBuffer()) ? TRUE : FALSE;
}
HX_RELEASE(pBuffer);
}
HX_RELEASE(pPreferences);
m_pSmilDocRenderer = new CSmil1DocumentRenderer(this, m_pContext);
m_pSmilDocRenderer->AddRef();
if (m_bUseNestedMeta)
{
IHXPersistentComponent* pPersistentComponent = NULL;
if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXPersistentComponentManager,
(void**)&m_pPersistentComponentManager))
{
m_pPersistentComponentManager->CreatePersistentComponent(pPersistentComponent);
pPersistentComponent->Init((IHXPersistentRenderer*)this);
pPersistentComponent->AddRendererAdviseSink((IHXRendererAdviseSink*)m_pSmilDocRenderer);
pPersistentComponent->AddGroupSink((IHXGroupSink*)m_pSmilDocRenderer);
rc = m_pPersistentComponentManager->AddPersistentComponent(pPersistentComponent);
generatePreFix();
}
}
else
{
IHXPersistenceManager* pMgr = 0;
if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXPersistenceManager,
(void**)&pMgr))
{
IUnknown* pUnk = 0;
if(HXR_OK == pMgr->GetPersistentComponent(pUnk))
{
rc = HXR_FAIL;
CSmil1SMILSyntaxErrorHandler errHandler(m_pContext);
errHandler.ReportError(SMILErrorMetaDatatype, NULL, 0);
pUnk->Release();
}
else if(HXR_OK == QueryInterface(IID_IUnknown, (void**)&pUnk))
{
pMgr->AddPersistentComponent(pUnk);
pUnk->Release();
generatePreFix();
}
pMgr->Release();
}
IHXDriverStreamManager* pDriverStreamMgr = 0;
if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXDriverStreamManager,
(void**)&pDriverStreamMgr))
{
if(HXR_OK == m_pSmilDocRenderer->QueryInterface(IID_IHXRendererAdviseSink,
(void**)&pRendererAdviseSink))
{
pDriverStreamMgr->AddRendererAdviseSink(pRendererAdviseSink);
pRendererAdviseSink->Release();
}
pDriverStreamMgr->Release();
}
IHXGroupManager* pGrpMgr = 0;
if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXGroupManager,
(void**)&pGrpMgr))
{
IHXGroupSink* pSnk = 0;
if(HXR_OK == m_pSmilDocRenderer->QueryInterface(
IID_IHXGroupSink, (void**)&pSnk))
{
pGrpMgr->AddSink(pSnk);
pSnk->Release();
}
}
HX_RELEASE(pGrpMgr);
}
return rc;
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IHXRenderer::EndStream
// Purpose:
// Called by client engine to inform the renderer that the stream
// is was rendering is closed.
//
STDMETHODIMP CSmil1Renderer::EndStream()
{
#if defined(HELIX_FEATURE_SMIL2)
m_bCSmil1EndStreamHasBeenCalled = TRUE;
#endif /* defined(HELIX_FEATURE_SMIL2). */
if(m_pPlayer)
{
if (m_bUseNestedMeta)
{
IHXPersistentComponent* pPersistentComponent = NULL;
IHXRendererAdviseSink* pRendererAdviseSink = 0;
if (HXR_OK == m_pPersistentComponentManager->GetPersistentComponent(m_pSmilDocRenderer->m_ulPersistentComponentID,
pPersistentComponent))
{
pPersistentComponent->RemoveRendererAdviseSink((IHXRendererAdviseSink*)m_pSmilDocRenderer);
pPersistentComponent->RemoveGroupSink((IHXGroupSink*)m_pSmilDocRenderer);
}
HX_RELEASE(pPersistentComponent);
}
else
{
IHXGroupManager* pGrpMgr = 0;
if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXGroupManager,
(void**)&pGrpMgr))
{
IHXGroupSink* pSnk = 0;
if(m_pSmilDocRenderer &&
HXR_OK == m_pSmilDocRenderer->QueryInterface(IID_IHXGroupSink,
(void**)&pSnk))
{
pGrpMgr->RemoveSink(pSnk);
pSnk->Release();
}
pGrpMgr->Release();
}
IHXDriverStreamManager* pStrmMgr = 0;
if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXDriverStreamManager,
(void**)&pStrmMgr))
{
IHXRendererAdviseSink* pSnk = 0;
if(m_pSmilDocRenderer &&
HXR_OK == m_pSmilDocRenderer->QueryInterface(
IID_IHXRendererAdviseSink, (void**)&pSnk))
{
pStrmMgr->RemoveRendererAdviseSink(pSnk);
pSnk->Release();
}
pStrmMgr->Release();
}
}
}
HX_RELEASE(m_pStream);
#if defined(HELIX_FEATURE_SMIL2)
if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
{
if (!m_pNextGenSmilRenderer)
{
return HXR_UNEXPECTED;
}
return m_pNextGenSmilRenderer->EndStream();
}
#endif /* defined(HELIX_FEATURE_SMIL2). */
if(m_pSmilDocRenderer)
{
m_pSmilDocRenderer->endStream();
}
return HXR_OK;
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IHXRenderer::OnHeader
// Purpose:
// Called by client engine when a header for this renderer is
// available. The header will arrive before any packets.
//
STDMETHODIMP CSmil1Renderer::OnHeader(IHXValues* pHeader)
{
// check stream and content versions so an upgrade can
// be called if necessary...
HX_RESULT rc = HXR_OK;
if (!pHeader)
{
return HXR_UNEXPECTED;
}
#if defined(HELIX_FEATURE_SMIL2)
// /Hang onto header in case we need to send it up to a higher-version
// SMIL renderer:
m_pHeader = pHeader;
m_pHeader->AddRef();
HX_ASSERT(!m_bIsHigherVersionSmilStreamFromOldSMIL1FF);
#endif /* defined(HELIX_FEATURE_SMIL2). */
BOOL bVersionOK = TRUE;
UINT16 uGroupCount = 0;
UINT16 uCurrentGroupID = 0;
UINT16 uSupportedType = 0; // G2 style by default
UINT32 ulStreamVersion = 0;
UINT32 ulContentVersion = 0;
IHXGroupManager* pGrpMgr = NULL;
if(HXR_OK == pHeader->GetPropertyULONG32("StreamVersion",
ulStreamVersion))
{
UINT32 ulMajorVersion = HX_GET_MAJOR_VERSION(ulStreamVersion);
UINT32 ulMinorVersion = HX_GET_MINOR_VERSION(ulStreamVersion);
if((ulMajorVersion > STREAM_MAJOR_VERSION) ||
(ulMinorVersion > STREAM_MINOR_VERSION &&
ulMajorVersion == STREAM_MAJOR_VERSION))
{
bVersionOK = FALSE;
}
}
if(bVersionOK &&
HXR_OK == pHeader->GetPropertyULONG32("ContentVersion",
ulContentVersion))
{
UINT32 ulMajorVersion = HX_GET_MAJOR_VERSION(ulContentVersion);
UINT32 ulMinorVersion = HX_GET_MINOR_VERSION(ulContentVersion);
if((ulMajorVersion > CONTENT_MAJOR_VERSION) ||
(ulMinorVersion > CONTENT_MINOR_VERSION &&
ulMajorVersion == CONTENT_MAJOR_VERSION))
{
bVersionOK = FALSE;
}
}
if(!bVersionOK)
{
AddToAutoUpgradeCollection((const char*) zm_pStreamMimeTypes[0], m_pContext);
rc = HXR_FAILED;
goto cleanup;
}
m_pPacketParser = new CSmilPacketParser;
m_pSmilDocRenderer->onHeader(pHeader);
if (m_bUseNestedMeta)
{
if (!m_pSmilDocRenderer->IsNestedMetaSupported(uSupportedType))
{
rc = HXR_INVALID_METAFILE;
goto cleanup;
}
switch (uSupportedType)
{
case 1:
// RP8 SS3 - limited SMIL in RAM support, blow-away all the existing groups
// when it is the last SMIL in RAM.
if (HXR_OK == m_pPlayer->QueryInterface(IID_IHXGroupManager, (void**)&pGrpMgr))
{
uGroupCount = pGrpMgr->GetGroupCount();
pGrpMgr->GetCurrentGroup(uCurrentGroupID);
if ((uCurrentGroupID + 1) == uGroupCount)
{
m_pSmilDocRenderer->m_bLastGroupInRAM20 = TRUE;
while(pGrpMgr && pGrpMgr->GetGroupCount() > 0)
{
pGrpMgr->RemoveGroup(0);
}
}
}
HX_RELEASE(pGrpMgr);
break;
default:
break;
}
}
else
{
if (HXR_OK == m_pPlayer->QueryInterface(IID_IHXGroupManager, (void**)&pGrpMgr))
{
while(pGrpMgr && pGrpMgr->GetGroupCount() > 0)
{
pGrpMgr->RemoveGroup(0);
}
}
HX_RELEASE(pGrpMgr);
}
cleanup:
return rc;
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IHXRenderer::OnPacket
// Purpose:
// Called by client engine when a packet for this renderer is
// due.
//
STDMETHODIMP CSmil1Renderer::OnPacket(IHXPacket* pPacket,
LONG32 lTimeOffset)
{
HX_RESULT rc = HXR_OK;
IHXBuffer* pBuffer = NULL;
#if defined(HELIX_FEATURE_SMIL2)
if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
{
if (!m_pNextGenSmilRenderer)
{
rc = HXR_UNEXPECTED;
goto cleanup;
}
rc = m_pNextGenSmilRenderer->OnPacket(pPacket, lTimeOffset);
goto cleanup;
}
#endif /* defined(HELIX_FEATURE_SMIL2). */
HX_ASSERT(lTimeOffset <= 0);
m_pSmilDocRenderer->m_ulPersistentComponentDelay = -lTimeOffset;
//Fix for PR 23352: if we already returned a fail value from
// a prior OnPacket(), don't process this OnPacket():
if (HXR_OK != m_lastOnPacketResult)
{
rc = m_lastOnPacketResult;
goto cleanup;
}
pBuffer = pPacket->GetBuffer();
if(pBuffer)
{
// /If parse() runs into a missing-quote situation,
// we should stop and display an error. Note that
// CSmilPacketParser::parse(..) does not keep track of
// line numbers; TODO: add line-number counting to it.
CSmilPacketParser::SMILPacketParseResult pktPrsRslt = CSmilPacketParser::SMILUnknown;
CSmilPacket* pSmilPacket = m_pPacketParser->parse(
pBuffer, pktPrsRslt);
if (CSmilPacketParser::SMILMissingQuote == pktPrsRslt)
{
CSmil1SMILSyntaxErrorHandler errHandler(m_pContext);
errHandler.ReportError(SMILErrorBadAttribute,
"missing quote", 0);
}
else if(pSmilPacket)
{
switch(pSmilPacket->m_type)
{
case CSmilPacket::SMILDocument:
{
#if defined(HELIX_FEATURE_SMIL2)
if (!m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
{
// /findSmilTagAndVersion returns TRUE if it finds
// the <smil> tag, regardless of the presence of
// a default namespace:
if (HXR_OK == findSmilTagAndVersion(pBuffer))
{
if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
{
HX_RESULT pSUS2R = setUpNextGenSmilRenderer();
if (HXR_OK!=pSUS2R || !m_pNextGenSmilRenderer)
{
rc = HXR_UNEXPECTED;
goto cleanup;
}
}
}
}
if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
{
rc = m_pNextGenSmilRenderer->OnPacket(pPacket,
lTimeOffset);
}
else
#endif /* defined(HELIX_FEATURE_SMIL2). */
{
rc = handleSMILDocumentPacket(
(CSmilDocumentPacket*)pSmilPacket);
}
if (HXR_OK != rc)
{
m_lastOnPacketResult = rc;
}
}
break;
default:
break;
}
delete pSmilPacket;
}
HX_RELEASE(pBuffer);
}
cleanup:
return rc;
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IHXRenderer::OnTimeSync
// Purpose:
// Called by client engine to inform the renderer of the current
// time relative to the streams synchronized time-line. The
// renderer should use this time value to update its display or
// render it's stream data accordingly.
//
STDMETHODIMP CSmil1Renderer::OnTimeSync(ULONG32 ulTime)
{
HX_RESULT rc = HXR_OK;
#if defined(HELIX_FEATURE_SMIL2)
if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
{
if (!m_pNextGenSmilRenderer)
{
rc = HXR_UNEXPECTED;
goto cleanup;
}
rc = m_pNextGenSmilRenderer->OnTimeSync(ulTime);
goto cleanup;
}
#endif /* defined(HELIX_FEATURE_SMIL2). */
if(m_pSmilDocRenderer)
{
rc = m_pSmilDocRenderer->onTimeSync(ulTime);
}
#if defined(HELIX_FEATURE_SMIL2)
cleanup:
#endif /* defined(HELIX_FEATURE_SMIL2). */
return rc;
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IHXRenderer::OnPreSeek
// Purpose:
// Called by client engine to inform the renderer that a seek is
// about to occur. The render is informed the last time for the
// stream's time line before the seek, as well as the first new
// time for the stream's time line after the seek will be completed.
//
STDMETHODIMP CSmil1Renderer::OnPreSeek(ULONG32 ulOldTime, ULONG32 ulNewTime)
{
HX_RESULT rc = HXR_OK;
#if defined(HELIX_FEATURE_SMIL2)
if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
{
if (!m_pNextGenSmilRenderer)
{
rc = HXR_UNEXPECTED;
goto cleanup;
}
rc = m_pNextGenSmilRenderer->OnPreSeek(ulOldTime, ulNewTime);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -