📄 sm1rendr.cpp
字号:
uTrackID,
ulCurrentTime,
pStatus);
}
HX_RESULT
CSmil1Renderer::HandleAddLayoutSiteGroup(IUnknown* pLSG)
{
HX_RESULT rc = HXR_OK;
IHXValues* pProps = NULL;
IHXPersistentRenderer* pPersistentParentRenderer = NULL;
pPersistentParentRenderer = m_pSmilDocRenderer->m_pPersistentParentRenderer;
// nested meta, get layout from its parent
if (pPersistentParentRenderer)
{
pProps = new CHXHeader();
if (pProps)
{
pProps->AddRef();
pProps->SetPropertyULONG32("PersistentType", m_persistentType);
}
rc = pPersistentParentRenderer->AttachElementLayout(m_pSmilDocRenderer->m_uPersistentGroupID,
m_pSmilDocRenderer->m_uPersistentTrackID,
(IHXRenderer*)pLSG,
NULL,
pProps);
}
else if (m_pPlayer)
{
IHXLayoutSiteGroupManager* pLSGMgr = 0;
if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXLayoutSiteGroupManager, (void**)&pLSGMgr))
{
rc = pLSGMgr->AddLayoutSiteGroup(pLSG);
pLSGMgr->Release();
}
}
HX_RELEASE(pProps);
return rc;
}
HX_RESULT
CSmil1Renderer::HandleRemoveLayoutSiteGroup(IUnknown* pLSG)
{
HX_RESULT rc = HXR_OK;
IHXPersistentRenderer* pPersistentParentRenderer = NULL;
pPersistentParentRenderer = m_pSmilDocRenderer->m_pPersistentParentRenderer;
// nested meta, remove layout from its parent
if (pPersistentParentRenderer)
{
rc = pPersistentParentRenderer->DetachElementLayout(pLSG);
}
else if (m_pPlayer)
{
IHXLayoutSiteGroupManager* pLSGMgr = 0;
if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXLayoutSiteGroupManager, (void**)&pLSGMgr))
{
rc = pLSGMgr->RemoveLayoutSiteGroup(pLSG);
pLSGMgr->Release();
}
}
return rc;
}
HX_RESULT
CSmil1Renderer::HandleAttachElementLayout(IUnknown* pLSG, IHXValues* pProps)
{
HX_RESULT rc = HXR_OK;
if (m_pPersistentComponentManager)
{
rc = m_pPersistentComponentManager->AttachPersistentComponentLayout(pLSG, pProps);
}
return rc;
}
HX_RESULT
CSmil1Renderer::handleSMILDocumentPacket(CSmilDocumentPacket* pPacket)
{
HX_RESULT rc = HXR_OK;
if(pPacket->m_version == RMA_DRIVER_VERSION)
{
CHXBuffer* pBuffer = new CHXBuffer;
pBuffer->AddRef();
BOOL bLastPacket = FALSE;
UINT32 ulDocLen = (UINT32)pPacket->m_document.GetLength();
HX_ASSERT(ulDocLen);
// /Extra safety check:
if (0 == ulDocLen)
{
rc = HXR_UNEXPECTED;
bLastPacket = FALSE;
}
else
{
pBuffer->Set((const BYTE*)(const char*)pPacket->m_document,
pPacket->m_document.GetLength());
m_ulTotalSMILPackets++;
bLastPacket = pPacket->m_ulTotalPackets == m_ulTotalSMILPackets;
rc = m_pSmilDocRenderer->onPacket(pBuffer, bLastPacket);
}
HX_RELEASE(pBuffer);
if(HXR_OK != rc)
{
// XML parsing error
UINT32 ulLineNumber = 0;
UINT32 ulColumnNumber = 0;
IHXBuffer* pErrorText = NULL;
m_pSmilDocRenderer->getErrorInfo(ulLineNumber,
ulColumnNumber, pErrorText);
const char* pActualErrorText = NULL;
if(pErrorText)
{
pActualErrorText = (const char*)pErrorText->GetBuffer();
}
CSmil1XMLSyntaxErrorHandler errHandler(m_pContext);
errHandler.ReportError(rc, pActualErrorText, ulLineNumber);
HX_RELEASE(pErrorText);
}
else if(bLastPacket)
{
//[SMIL 1.0 compliance] Handle error from setDocument()
// otherwise it "plays" (nothing for 20 seconds) when it
// should halt under error conditions:
rc = m_pSmilDocRenderer->setDocument(m_pURLFragment);
}
}
return rc;
}
void
CSmil1Renderer::generatePreFix()
{
// get the protocol/server for later...
IHXStreamSource* pSource = 0;
m_pStream->GetSource(pSource);
HX_ASSERT(pSource);
if (!pSource)
{
return;
}
const char* pURL = pSource->GetURL();
HX_ASSERT(pURL);
if (!pURL)
{
return;
}
CHXURL::GeneratePrefixRootFragment(pURL, m_urlPrefix, m_urlRoot, m_pURLFragment);
HX_RELEASE(pSource);
return;
}
#if defined(HELIX_FEATURE_SMIL2)
HX_RESULT
CSmil1Renderer::findValidDefaultNamespace(IHXBuffer* pStartOfFile)
{
HX_RESULT pnreslt = HXR_OK;
const char* pSmilTag = NULL;
const char* pCloseOfSmilTag = NULL;
const char* pXmlns = NULL;
const char* pXmlnsOpenQuotationMark = NULL;
const char* pBuf = NULL;
ULONG32 ulBufLen = 0;
const char* pEqualsSign = NULL;
const char* pTmp = NULL;
char* pTmp2 = NULL;
char* pszStartOfFile = NULL;
ULONG32 ulCount = 0;
LONG32 lNumCommentsOpen = 0;
if (!pStartOfFile)
{
pnreslt = HXR_BUFFERTOOSMALL;
goto cleanup;
}
// /Fixes PR 59282: pStartOfFile is not necessarily NULL-terminated,
// so we have to limit our access of it to the size of the buffer:
ulBufLen = pStartOfFile->GetSize();
pBuf = (const char*)pStartOfFile->GetBuffer();
if (!pBuf || !ulBufLen)
{
pnreslt = HXR_BUFFERTOOSMALL;
goto cleanup;
}
pszStartOfFile = new char[ulBufLen+1];
if (!pszStartOfFile)
{
pnreslt = HXR_OUTOFMEMORY;
goto cleanup;
}
// /Now, walk through and copy each character from non-NULL terminated buf:
pTmp = pBuf;
pTmp2 = pszStartOfFile;
while (*pTmp && ulCount<ulBufLen)
{
*pTmp2 = *pTmp;
pTmp++;
pTmp2++;
ulCount++;
}
pszStartOfFile[ulCount] = '\0'; // /NULL-terminate it.
// /Now, let's walk through the start of pszStartOfFile looking for
// namespace declaration(s) inside the <smil ...> tag, and make sure that
// the smil tag is NOT inside of a comment:
pTmp = pszStartOfFile;
while (*pTmp)
{
if (0==strncmp(pTmp, "<!--", 4) )
{
lNumCommentsOpen++;
pTmp+=4;
}
else if (0==strncmp(pTmp, "-->", 3) )
{
lNumCommentsOpen--;
pTmp+=3;
}
else if (lNumCommentsOpen<=0 && 0==strncmp(pTmp, "<smil", 5) )
{
pSmilTag = pTmp; // /We found the smil tag outside of a comment.
break;
}
else
{
pTmp++;
}
}
if (!pSmilTag || ulBufLen-(pSmilTag-pszStartOfFile) < 6) // /6==min size: "<smil>"
{
// /There had better be a <smil...> tag!
pnreslt = HXR_UNEXPECTED;
goto cleanup;
}
pCloseOfSmilTag = strchr(pSmilTag, '>');
// /Add 6 so that we don't allow "<smilxmlns ..." (which is invalid):
pXmlns = strstr(pSmilTag+6, "xmlns");
if (pXmlns && isspace(*(pXmlns-1)) ) // /"xmlns" must follow a space.
{
pEqualsSign = strchr(pXmlns, '=');
if (pEqualsSign)
{
pXmlnsOpenQuotationMark = strchr(pXmlns, '\"');
}
}
if (pXmlns && pEqualsSign && pXmlnsOpenQuotationMark &&
(!pCloseOfSmilTag || pXmlns<pCloseOfSmilTag))
{
m_bIsHigherVersionSmilStreamFromOldSMIL1FF = TRUE;
// /First, make sure there is nothing but whitespace between
// the "xmlns" and the '=' as well as between the '=' and the
// quotation mark:
char* pTmp = (char*)(pXmlns + strlen("xmlns"));
while (pTmp<pEqualsSign)
{
if (!isspace(*pTmp))
{
m_bIsHigherVersionSmilStreamFromOldSMIL1FF = FALSE;
break;
}
pTmp++;
}
pTmp = (char*)(pEqualsSign+1);
while(pTmp<pXmlnsOpenQuotationMark)
{
if (!isspace(*pTmp) && *pTmp != '\\')
{
m_bIsHigherVersionSmilStreamFromOldSMIL1FF = FALSE;
break;
}
pTmp++;
}
char* pDefaultNamespace = (char*)pXmlnsOpenQuotationMark+1;
if (strlen(pDefaultNamespace) > 0)
{
char* pXmlnsCloseQuotationMark = strstr(pDefaultNamespace, "\\\"");
if (pXmlnsCloseQuotationMark)
{
*pXmlnsCloseQuotationMark = '\0'; // /NULL-terminate it.
}
else
{
HX_ASSERT(pXmlnsCloseQuotationMark);
pnreslt = HXR_FAIL;
goto cleanup;
}
}
HX_RELEASE(m_pDefaultNamespace);
if (m_pCommonClassFactory &&
HXR_OK == m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer,
(void**)&m_pDefaultNamespace) )
{
LONG32 lLen = strlen(pDefaultNamespace);
if (lLen > 0 && lLen < 10000) // /sanity check
{
m_pDefaultNamespace->Set((const BYTE*)pDefaultNamespace,
lLen + 1);
}
pnreslt = HXR_OK;
}
}
cleanup:
if (pszStartOfFile)
{
HX_VECTOR_DELETE(pszStartOfFile);
}
return pnreslt;
}
#endif /* defined(HELIX_FEATURE_SMIL2). */
#if defined(HELIX_FEATURE_SMIL2)
// /The following two methods are used for looking for and handling SMIL 2+
// streams coming from SMIL 1.0 File Format plugins (that didn't have smarts
// to look for default namespace which identifies the SMIL file version):
HX_RESULT
CSmil1Renderer::findSmilTagAndVersion(IHXBuffer* pFileChunk)
{
HX_RESULT rc = HXR_OK;
ULONG32 ulLen = 0;
if (!pFileChunk || (ulLen=pFileChunk->GetSize()) < 6)
{
rc = HXR_FAILED;
goto cleanup;
}
rc = findValidDefaultNamespace(pFileChunk);
cleanup:
return rc;
}
HX_RESULT
CSmil1Renderer::setUpNextGenSmilRenderer()
{
HX_RESULT rc = HXR_OK;
rc = CSmilRenderer::HXCreateInstance((IUnknown**)(&m_pNextGenSmilRenderer));
if (HXR_OK == rc && m_pNextGenSmilRenderer)
{
IHXSmilToSmilRendererCommunicator* pSmilToSmilComm = NULL;
if (HXR_OK == m_pNextGenSmilRenderer->
QueryInterface(IID_IHXSmilToSmilRendererCommunicator,
(void**) &pSmilToSmilComm))
{
if (HXR_OK ==
pSmilToSmilComm->InitSmilStreamProxiedByOtherRenderer(
m_pDefaultNamespace))
{
rc = m_pNextGenSmilRenderer->InitPlugin(m_pContext);
}
HX_RELEASE(pSmilToSmilComm);
}
if (HXR_OK == rc)
{
// /XXXEH- note that the REF parameters in GetPluginInfo() and
// GetRendererInfo are set by the callee, but we can't do
// anything with the values passed back as we've already set these
// to our own vals and there's no way to re-set them in the core:
BOOL bLoadMultiple = FALSE;
const char* pszDescription = NULL;
const char* pszCopyright = NULL;
const char* pszMoreInfoURL = NULL;
ULONG32 ulVersionNumber = 0;
rc = m_pNextGenSmilRenderer->GetPluginInfo(bLoadMultiple,
pszDescription, pszCopyright, pszMoreInfoURL,
ulVersionNumber);
if (HXR_OK == rc)
{
const char** ppStreamMimeTypes = NULL;
ULONG32 ulInitialGranularity = m_ulGranularity;
rc = m_pNextGenSmilRenderer->GetRendererInfo(
ppStreamMimeTypes, ulInitialGranularity);
}
if (HXR_OK == rc)
{
HX_ASSERT(m_bCSmil1StartStreamHasBeenCalled);
rc = m_pNextGenSmilRenderer->StartStream(m_pStream,
m_pPlayer);
}
if (HXR_OK == rc && m_bCSmil1EndStreamHasBeenCalled)
{
rc = m_pNextGenSmilRenderer->EndStream();
}
if (HXR_OK == rc)
{
if (!m_pHeader)
{
HX_ASSERT(m_pHeader);
rc = HXR_UNEXPECTED;
}
else
{
rc = m_pNextGenSmilRenderer->OnHeader(m_pHeader);
}
}
if (HXR_OK == rc && m_bCSmil1GetDisplayTypeHasBeenCalled)
{
HX_DISPLAY_TYPE ulFlags = HX_DISPLAY_NONE;
IHXBuffer* pBuffer = NULL;
rc = m_pNextGenSmilRenderer->GetDisplayType(ulFlags, pBuffer);
if (pBuffer)
{
// /XXXEH- We can't use it here, so just clean it up:
HX_DELETE(pBuffer);
}
}
if (HXR_OK == rc && m_bCSmil1InitializeStatisticsHasBeenCalled)
{
rc = m_pNextGenSmilRenderer->InitializeStatistics(m_ulRegistryID);
}
#if defined(DO_INIT_PERSISTENT_ON_NEXTGEN_SMILREND)
if (HXR_OK == rc && m_bCSmil1InitPersistenHasBeenCalled)
{
// /NOTE: it's perfectly OK for m_pPersistentParent to be NULL
rc = m_pNextGenSmilRenderer->InitPersistent(
m_ulPersistentComponentID, m_uPersistentGroupID,
m_uPersistentTrackID, m_pPersistentParent);
}
#endif
if (HXR_OK == rc && m_bCSmil1GetElementPropertiesHasBeenCalled)
{
IHXValues* pProperties = NULL;
// /XXXEH- TODO: we need to notify the original caller of this
// of the next-gen renderer's setting of pProperties.
rc = m_pNextGenSmilRenderer->GetElementProperties(
m_uGroupID, m_uTrackID, pProperties);
}
if (HXR_OK == rc && m_bCSmil1RemoveLayoutSiteGroupHasBeenCalled)
{
// /XXXEH- Need to handle this (unexpected) case by saving the
// removed layout site group (which could differ from the
// add site layout group, m_pLayoutSiteGroup (or not?):
HX_ASSERT(!m_bCSmil1RemoveLayoutSiteGroupHasBeenCalled);
}
}
}
return rc;
}
#endif /* defined(HELIX_FEATURE_SMIL2). */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -