📄 smlrendr.cpp
字号:
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::AddRef
// Purpose:
// Everyone usually implements this the same... feel free to use
// this implementation.
//
STDMETHODIMP_(ULONG32) CSmilRenderer::AddRef()
{
return InterlockedIncrement(&m_lRefCount);
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::Release
// Purpose:
// Everyone usually implements this the same... feel free to use
// this implementation.
//
STDMETHODIMP_(ULONG32) CSmilRenderer::Release()
{
if (InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
// *** IHXRenderer methods ***
/////////////////////////////////////////////////////////////////////////
// Method:
// IHXRenderer::StartStream
// Purpose:
// Called by client engine to inform the renderer of the stream it
// will be rendering. The stream interface can provide access to
// its source or player. This method also provides access to the
// primary client controller interface.
//
STDMETHODIMP CSmilRenderer::StartStream
(
IHXStream* pStream,
IHXPlayer* pPlayer
)
{
MLOG_FLOW(m_pErrorMessages, "CSmilRenderer::StartStream(0x%08x,0x%08x) this=0x%08x\n",
pStream, pPlayer, this);
HX_RESULT rc = HXR_OK;
// Save for later use!
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;
IHXRendererAdviseSink* pRendererAdviseSink = NULL;
IUnknown* pUnknown = NULL;
m_pPlayer->QueryInterface(IID_IUnknown, (void**) &pUnknown);
if (pUnknown)
{
::getBooleanPreference(pUnknown, "useNestedMeta", m_bUseNestedMeta);
}
HX_RELEASE(pUnknown);
m_pSmilDocRenderer = new CSmilDocumentRenderer(this, m_pContext);
m_pSmilDocRenderer->AddRef();
if (m_bUseNestedMeta &&
// /For handling case where SMIL 1.0 renderer is passing this higher-
// than-1.0-version stream to this renderer, we don't want to do what
// the SMIL 1.0 renderer has already set up with the core:
!m_bStreamProxiedByOtherRenderer)
{
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);
}
}
else if (!m_bStreamProxiedByOtherRenderer)
{
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;
CSmilSMILSyntaxErrorHandler errHandler(m_pContext);
errHandler.ReportError(SMILErrorMetaDatatype, NULL, 0);
pUnk->Release();
}
else if(HXR_OK == QueryInterface(IID_IUnknown, (void**)&pUnk))
{
pMgr->AddPersistentComponent(pUnk);
pUnk->Release();
}
pMgr->Release();
}
IHXDriverStreamManager* pDriverStreamMgr = 0;
if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXDriverStreamManager,
(void**)&pDriverStreamMgr))
{
if(!m_bStreamProxiedByOtherRenderer &&
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(!m_bStreamProxiedByOtherRenderer &&
HXR_OK == m_pSmilDocRenderer->QueryInterface(
IID_IHXGroupSink, (void**)&pSnk))
{
pGrpMgr->AddSink(pSnk);
pSnk->Release();
}
}
HX_RELEASE(pGrpMgr);
}
generatePreFix();
return rc;
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IHXRenderer::EndStream
// Purpose:
// Called by client engine to inform the renderer that the stream
// is was rendering is closed.
//
STDMETHODIMP CSmilRenderer::EndStream()
{
MLOG_FLOW(m_pErrorMessages,
"CSmilRenderer::EndStream() this=0x%08x\n", this);
if(m_pSmilDocRenderer)
{
m_pSmilDocRenderer->endStream();
}
if(m_pPlayer)
{
if (m_bUseNestedMeta && !m_bStreamProxiedByOtherRenderer)
{
IHXPersistentComponent* pPersistentComponent = NULL;
IHXRendererAdviseSink* pRendererAdviseSink = 0;
if(m_pPersistentComponentManager && HXR_OK == m_pPersistentComponentManager->GetPersistentComponent( m_pSmilDocRenderer->m_ulPersistentComponentID,
pPersistentComponent))
{
pPersistentComponent->RemoveRendererAdviseSink((IHXRendererAdviseSink*)m_pSmilDocRenderer);
pPersistentComponent->RemoveGroupSink((IHXGroupSink*)m_pSmilDocRenderer);
}
HX_RELEASE(pPersistentComponent);
}
else if (!m_bStreamProxiedByOtherRenderer)
{
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();
}
}
IHXClientAdviseSink* pSnk = NULL;
if(!m_bStreamProxiedByOtherRenderer &&
m_pSmilDocRenderer &&
HXR_OK == m_pSmilDocRenderer->QueryInterface(
IID_IHXClientAdviseSink, (void**)&pSnk))
{
m_pPlayer->RemoveAdviseSink(pSnk);
HX_RELEASE(pSnk);
}
}
HX_RELEASE(m_pStream);
// /See if the player has child players who need to be stopped:
if (m_pPlayer)
{
IHXPlayerNavigator* pPlayerNavRoot = NULL;
HX_RESULT pnrslt = m_pPlayer->QueryInterface(IID_IHXPlayerNavigator,
(void**)&pPlayerNavRoot);
if (HXR_OK == pnrslt)
{
UINT16 uiChild = pPlayerNavRoot->GetNumChildPlayer();
while (uiChild > 0)
{
IHXPlayer* pChildPlayer = NULL;
// /GetChildPlayer addrefs pChildPlayer:
pPlayerNavRoot->GetChildPlayer(uiChild-1, pChildPlayer);
HX_ASSERT(pChildPlayer);
if (pChildPlayer)
{
pChildPlayer->Stop();
HX_RELEASE(pChildPlayer);
}
uiChild--;
}
HX_RELEASE(pPlayerNavRoot);
}
}
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 CSmilRenderer::OnHeader(IHXValues* pHeader)
{
MLOG_FLOW(m_pErrorMessages,
"CSmilRenderer::OnHeader(0x%08x) this=0x%08x\n", pHeader, this);
// check stream and content versions so an upgrade can
// be called if necessary...
BOOL bVersionOK = TRUE;
UINT32 ulStreamVersion = 0;
UINT32 ulContentVersion = 0;
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)
{
IHXUpgradeCollection* pUpColl = NULL;
if(m_pPlayer &&
(HXR_OK == m_pPlayer->QueryInterface(IID_IHXUpgradeCollection,
(void**)&pUpColl)))
{
CHXBuffer* pBuffer = new CHXBuffer;
pBuffer->AddRef();
pBuffer->Set((BYTE*)SMIL20_AND_UP_STREAM_MIME_TYPE,
strlen(SMIL20_AND_UP_STREAM_MIME_TYPE)+1);
pUpColl->Add(eUT_Required, pBuffer, 0, 0);
HX_RELEASE(pBuffer);
HX_RELEASE(pUpColl);
}
return HXR_FAIL;
}
m_pPacketParser = new CSmilPacketParser;
m_pSmilDocRenderer->onHeader(pHeader);
if (!m_pSmilDocRenderer->IsNestedMetaSupported())
{
return HXR_INVALID_METAFILE;
}
IHXClientAdviseSink* pSnk = 0;
if(!m_bStreamProxiedByOtherRenderer &&
HXR_OK == m_pSmilDocRenderer->QueryInterface(
IID_IHXClientAdviseSink, (void**)&pSnk))
{
m_pPlayer->AddAdviseSink(pSnk);
HX_RELEASE(pSnk);
}
if (!m_bUseNestedMeta)
{
/* SMIL renderer currently removes previously added
* groups, if any. This is to solve the case where we have
* SMIL file within a RAM file. We will do something more
* sensible later.
*/
IHXGroupManager* pGrpMgr = 0;
if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXGroupManager,
(void**)&pGrpMgr))
{
while(pGrpMgr && pGrpMgr->GetGroupCount() > 0)
{
pGrpMgr->RemoveGroup(0);
}
}
HX_RELEASE(pGrpMgr);
}
return HXR_OK;
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IHXRenderer::OnPacket
// Purpose:
// Called by client engine when a packet for this renderer is
// due.
//
STDMETHODIMP CSmilRenderer::OnPacket(IHXPacket* pPacket,
LONG32 lTimeOffset)
{
MLOG_FLOW(m_pErrorMessages,
"CSmilRenderer::OnPacket(0x%08x,%ld) this=0x%08x\n",
pPacket, lTimeOffset, this);
HX_RESULT rc = HXR_OK;
HX_ASSERT(lTimeOffset <= 0);
//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)
{
return m_lastOnPacketResult;
}
IHXBuffer* 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)
{
CSmilSMILSyntaxErrorHandler errHandler(m_pContext);
errHandler.ReportError(SMILErrorBadAttribute,
"missing quote", 0);
}
else if(pSmilPacket)
{
switch(pSmilPacket->m_type)
{
case CSmilPacket::SMILDocument:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -