sm1rendr.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:52k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: sm1rendr.cpp,v 1.3.2.1 2004/07/09 01:57:37 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #if defined (_AIX)
  50. #include <X11/Xlib.h>
  51. #endif
  52. #include <stdio.h>
  53. #include "sm1rendr.ver"
  54. #include "hxtypes.h"
  55. #include "hxwintyp.h"
  56. #include "chxxtype.h"
  57. #include "hxcom.h"
  58. #include "hxcomm.h"
  59. #include "ihxpckts.h"
  60. #include "hxfiles.h"
  61. #include "hxcore.h"
  62. #include "hxprefs.h"
  63. #include "hxrendr.h"
  64. #include "hxasm.h"
  65. #include "hxplugn.h"
  66. #include "hxengin.h"
  67. #include "hxwin.h"
  68. #include "hxgroup.h"
  69. #include "hxsite2.h"
  70. #include "hxclsnk.h"
  71. #include "hxerror.h"
  72. #include "hxupgrd.h"
  73. #include "hxprefs.h"
  74. #include "hxvsurf.h"
  75. #include "hxcmenu.h"
  76. #include "hxhyper.h"
  77. #include "hxmon.h" // for IHXRegistry
  78. #include "hxxres.h"
  79. #include "hxxrsmg.h"
  80. #include "hxmeta1.h"   /* renamed for SHAZAM; used to be hxmeta.h */
  81. #include "hxsm2sm.h"
  82. #include "hxxml.h"
  83. #include "hxxmlprs.h"
  84. #include "xmlreslt.h"
  85. #include "hxstack.h"
  86. #include "hxslist.h"
  87. #include "hxstring.h"
  88. #include "hxstrutl.h"
  89. #include "hxmap.h"
  90. #include "chxpckts.h"
  91. #include "hxmap.h"
  92. #include "hxurl.h"
  93. #include "asmrulep.h"
  94. #include "hxver.h"
  95. #include "smlpkt.h"
  96. #include "sm1elem.h"
  97. #include "sm1doc.h"
  98. #include "sm1error.h"
  99. #include "smilres.h"
  100. #include "xmlres.h"
  101. #include "smlrendr.h" /* for SMIL2+ renderer (CSmilRenderer) */
  102. #include "sm1rendr.h"
  103. #include "addupcol.h"
  104. /* We should really define it in a common header file */
  105. #if defined (_WINDOWS ) || defined (WIN32)
  106. #define OS_SEPARATOR_CHAR '\'
  107. #define OS_SEPARATOR_STRING "\"
  108. #elif defined (_UNIX)
  109. #define OS_SEPARATOR_CHAR '/'
  110. #define OS_SEPARATOR_STRING "/"
  111. #elif defined (_MACINTOSH)
  112. #define OS_SEPARATOR_CHAR ':'
  113. #define OS_SEPARATOR_STRING ":"
  114. #endif // defined (_WINDOWS ) || defined (WIN32)
  115. #include "hxheap.h"
  116. #ifdef _DEBUG
  117. #undef HX_THIS_FILE
  118. static const char HX_THIS_FILE[] = __FILE__;
  119. #endif
  120. #ifdef _WINDOWS
  121. extern HINSTANCE g_hInstance;
  122. #endif
  123. // /Defining the following fixes PR 62481 and seems to work fine with other
  124. // SMIL 2.0 content coming from a SMIL 1.0 File Format plug-in:
  125. #define DO_INIT_PERSISTENT_ON_NEXTGEN_SMILREND    1
  126. static const UINT32 INITIAL_GRANULARITY = 66;
  127. /****************************************************************************
  128.  * 
  129.  *  Method:
  130.  * 
  131.  * HXCreateInstance()
  132.  * 
  133.  *  Purpose:
  134.  * 
  135.  * Function implemented by all plugin DLL's to create an instance of 
  136.  * any of the objects supported by the DLL. This method is similar to 
  137.  * Window's CoCreateInstance() in its purpose, except that it only 
  138.  * creates objects from this plugin DLL.
  139.  *
  140.  * NOTE: Aggregation is never used. Therefore and outer unknown is
  141.  * not passed to this function, and you do not need to code for this
  142.  * situation.
  143.  * 
  144.  */
  145. HX_RESULT STDAPICALLTYPE CSmil1Renderer::HXCreateInstance(IUnknown** ppIUnknown)
  146. {
  147.     HX_RESULT retVal = HXR_FAIL;
  148.     if (ppIUnknown)
  149.     {
  150.         CSmil1Renderer* pObj = new CSmil1Renderer();
  151.         if (pObj)
  152.         {
  153.             retVal = pObj->QueryInterface(IID_IUnknown, (void**) ppIUnknown);
  154.             if (FAILED(retVal))
  155.             {
  156.                 HX_DELETE(pObj);
  157.             }
  158.         }
  159.     }
  160.     return retVal;
  161. }
  162. HX_RESULT STDAPICALLTYPE CSmil1Renderer::CanUnload2()
  163. {
  164.     return ((CHXBaseCountingObject::ObjectsActive() > 0) ? HXR_FAIL : HXR_OK );
  165. }
  166. const char* const CSmil1Renderer::zm_pName       = "SMIL 1.0";
  167. const char* const CSmil1Renderer::zm_pDescription    = "RealNetworks RMA Driver Renderer Plugin";
  168. const char* const CSmil1Renderer::zm_pCopyright      = HXVER_COPYRIGHT;
  169. const char* const CSmil1Renderer::zm_pMoreInfoURL    = HXVER_MOREINFO;
  170. const char* const CSmil1Renderer::zm_pStreamMimeTypes[] = { "application/vnd.rn-rmadriver", "application/rma-driver", NULL };
  171. /************************************************************************
  172.  *  Method:
  173.  *    IHXPlugin::InitPlugin
  174.  *  Purpose:
  175.  *    Initializes the plugin for use. This interface must always be
  176.  *    called before any other method is called. This is primarily needed 
  177.  *    so that the plugin can have access to the context for creation of
  178.  *    IHXBuffers and IMalloc.
  179.  */
  180. STDMETHODIMP CSmil1Renderer::InitPlugin(IUnknown* /*IN*/ pContext)
  181. {
  182. #if defined(HELIX_FEATURE_SMIL2)
  183.     HX_ASSERT(!m_bIsHigherVersionSmilStreamFromOldSMIL1FF);
  184. #endif /* defined(HELIX_FEATURE_SMIL2). */
  185.     m_pContext = pContext;
  186.     m_pContext->AddRef();
  187.     m_pContext->QueryInterface(IID_IHXCommonClassFactory,
  188.     (void**)&m_pCommonClassFactory);
  189.     return HXR_OK;
  190. }
  191. /************************************************************************
  192.  *  Method:
  193.  *    IHXPlugin::GetPluginInfo
  194.  *  Purpose:
  195.  *    Returns the basic information about this plugin. Including:
  196.  *
  197.  *    bLoadMultiple whether or not this plugin DLL can be loaded
  198.  * multiple times. All File Formats must set
  199.  * this value to TRUE.
  200.  *    pDescription which is used in about UIs (can be NULL)
  201.  *    pCopyright which is used in about UIs (can be NULL)
  202.  *    pMoreInfoURL which is used in about UIs (can be NULL)
  203.  */
  204. STDMETHODIMP CSmil1Renderer::GetPluginInfo
  205. (
  206.     REF(BOOL)        /*OUT*/ bLoadMultiple,
  207.     REF(const char*) /*OUT*/ pDescription,
  208.     REF(const char*) /*OUT*/ pCopyright,
  209.     REF(const char*) /*OUT*/ pMoreInfoURL,
  210.     REF(ULONG32)     /*OUT*/ ulVersionNumber
  211. )
  212. {
  213. #if defined(HELIX_FEATURE_SMIL2)
  214.     HX_ASSERT(!m_bIsHigherVersionSmilStreamFromOldSMIL1FF);
  215. #endif /* defined(HELIX_FEATURE_SMIL2). */
  216.     bLoadMultiple = TRUE;   // Must be true for file formats.
  217.     pDescription    = (const char*) zm_pDescription;
  218.     pCopyright     = (const char*) zm_pCopyright;
  219.     pMoreInfoURL    = (const char*) zm_pMoreInfoURL;
  220.     ulVersionNumber = TARVER_ULONG32_VERSION;
  221.     return HXR_OK;
  222. }
  223. /************************************************************************
  224.  *  Method:
  225.  *    IHXPlugin::GetRendererInfo
  226.  *  Purpose:
  227.  *    If this object is a file format object this method returns
  228.  *    information vital to the instantiation of file format plugins.
  229.  *    If this object is not a file format object, it should return
  230.  *    HXR_UNEXPECTED.
  231.  */
  232. STDMETHODIMP CSmil1Renderer::GetRendererInfo
  233. (
  234.     REF(const char**) /*OUT*/ pStreamMimeTypes,
  235.     REF(UINT32)      /*OUT*/ unInitialGranularity
  236. )
  237. {
  238. #if defined(HELIX_FEATURE_SMIL2)
  239.     HX_ASSERT(!m_bIsHigherVersionSmilStreamFromOldSMIL1FF);
  240. #endif /* defined(HELIX_FEATURE_SMIL2). */
  241.     pStreamMimeTypes = (const char**) zm_pStreamMimeTypes;
  242.     unInitialGranularity = m_ulGranularity;
  243.     return HXR_OK;
  244. }
  245. CSmil1Renderer::CSmil1Renderer()
  246. : m_lRefCount(0)
  247. , m_pContext(NULL)
  248. , m_pStream(NULL)
  249. , m_pPlayer(NULL)
  250. , m_ulLastTime(0)
  251. , m_pCommonClassFactory(0)
  252. , m_pPacketParser(0)
  253. , m_pSmilDocRenderer(0)
  254. , m_pEngine(0)
  255. , m_pClientContext(0)
  256. , m_uLayoutRule(0)
  257. , m_uSourceRule(0)
  258. , m_ulTotalSMILPackets(0)
  259. , m_ulGranularity(INITIAL_GRANULARITY)
  260. , m_pURLFragment(0)
  261. , m_lastOnPacketResult(HXR_OK)
  262. #if defined(HELIX_FEATURE_SMIL2)
  263. // /All of the following are needed for handling SMIL 2+ streams:
  264. , m_pNextGenSmilRenderer(NULL)
  265. , m_bIsHigherVersionSmilStreamFromOldSMIL1FF(FALSE)
  266. , m_pHeader(NULL)
  267. , m_pDefaultNamespace(NULL)
  268. , m_bCSmil1StartStreamHasBeenCalled(FALSE)
  269. , m_bCSmil1EndStreamHasBeenCalled(FALSE)
  270. , m_bCSmil1GetDisplayTypeHasBeenCalled(FALSE)
  271. , m_bCSmil1InitializeStatisticsHasBeenCalled(FALSE)
  272. , m_bCSmil1InitPersistenHasBeenCalled(FALSE)
  273. , m_bCSmil1GetElementPropertiesHasBeenCalled(FALSE)
  274. , m_bCSmil1RemoveLayoutSiteGroupHasBeenCalled(FALSE)
  275. , m_ulPersistentComponentID(0)
  276. , m_uPersistentGroupID(0)
  277. , m_uPersistentTrackID(0)
  278. , m_pPersistentParent(NULL)
  279. , m_ulRegistryID(0)
  280. , m_uGroupID(0)
  281. , m_uTrackID(0)
  282. // /End "...handling SMIL 2+ streams".
  283. #endif /* defined(HELIX_FEATURE_SMIL2). */
  284. , m_bUseNestedMeta(TRUE)
  285. , m_pPersistentComponentManager(NULL)    
  286. , m_ulPersistentVersion(0)
  287. , m_persistentType(PersistentSMIL)
  288. {
  289. #if defined(_DEBUG) && defined(XXXMEH_CHECK_FOR_LEAKS)
  290.     char szDbgStr[128]; /* Flawfinder: ignore */
  291.     sprintf(szDbgStr, "CON CSmil1Renderer 0x%08xn", this); /* Flawfinder: ignore */
  292.     OutputDebugString(szDbgStr);
  293. #endif
  294.     m_ulPersistentVersion = HX_ENCODE_PROD_VERSION(1, 0, 0, 0);
  295. };
  296. CSmil1Renderer::~CSmil1Renderer()
  297. {
  298. #if defined(_DEBUG) && defined(XXXMEH_CHECK_FOR_LEAKS)
  299.     char szDbgStr[128]; /* Flawfinder: ignore */
  300.     sprintf(szDbgStr, "DES CSmil1Renderer 0x%08xn", this); /* Flawfinder: ignore */
  301.     OutputDebugString(szDbgStr);
  302. #endif
  303.     if(m_pSmilDocRenderer)
  304.     {
  305. m_pSmilDocRenderer->close(this);
  306. HX_RELEASE(m_pSmilDocRenderer);
  307.     }
  308. #if defined(HELIX_FEATURE_SMIL2)
  309.     HX_RELEASE(m_pDefaultNamespace);
  310.     HX_RELEASE(m_pNextGenSmilRenderer);
  311.     HX_RELEASE(m_pHeader);
  312.     HX_RELEASE(m_pPersistentParent);
  313. #endif /* defined(HELIX_FEATURE_SMIL2). */
  314.     HX_RELEASE(m_pPersistentComponentManager);
  315.     HX_RELEASE(m_pContext);
  316.     HX_RELEASE(m_pClientContext);
  317.     HX_RELEASE(m_pStream);
  318.     HX_RELEASE(m_pEngine);
  319.     HX_RELEASE(m_pCommonClassFactory);
  320.     HX_DELETE(m_pPacketParser);
  321.     HX_RELEASE(m_pPlayer);
  322.     HX_VECTOR_DELETE(m_pURLFragment);
  323. }
  324. // *** IUnknown methods ***
  325. /////////////////////////////////////////////////////////////////////////
  326. //  Method:
  327. // IUnknown::QueryInterface
  328. //  Purpose:
  329. // Implement this to export the interfaces supported by your 
  330. // object.
  331. //
  332. STDMETHODIMP CSmil1Renderer::QueryInterface(REFIID riid, void** ppvObj)
  333. {
  334.     if (IsEqualIID(riid, IID_IUnknown))
  335.     {
  336. AddRef();
  337. *ppvObj = this;
  338. return HXR_OK;
  339.     }
  340.     else if (IsEqualIID(riid, IID_IHXPlugin))
  341.     {
  342. AddRef();
  343. *ppvObj = (IHXPlugin*)this;
  344. return HXR_OK;
  345.     }
  346.     else if (IsEqualIID(riid, IID_IHXRenderer))
  347.     {
  348. AddRef();
  349. *ppvObj = (IHXRenderer*)this;
  350. return HXR_OK;
  351.     }
  352.     else if (IsEqualIID(riid, IID_IHXSiteUser))
  353.     {
  354. AddRef();
  355. *ppvObj = (IHXSiteUser*)this;
  356. return HXR_OK;
  357.     }
  358.     else if (IsEqualIID(riid, IID_IHXStatistics))
  359.     {
  360. AddRef();
  361. *ppvObj = (IHXStatistics*)this;
  362. return HXR_OK;
  363.     }
  364.     else if (IsEqualIID(riid, IID_IHXPersistentRenderer))
  365.     {
  366. AddRef();
  367. *ppvObj = (IHXPersistentRenderer*)this;
  368. return HXR_OK;
  369.     }
  370.     else if (m_pSmilDocRenderer &&
  371.      HXR_OK == m_pSmilDocRenderer->QueryInterface(riid, ppvObj))
  372.     {
  373. return HXR_OK;
  374.     }
  375. #if defined(HELIX_FEATURE_SMIL2)
  376.     else if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
  377.     {
  378. if (!m_pNextGenSmilRenderer)
  379. {
  380.     return HXR_UNEXPECTED;
  381. }
  382. if (HXR_OK ==
  383. m_pNextGenSmilRenderer->QueryInterface(riid, ppvObj))
  384. {
  385.     return HXR_OK;
  386. }
  387.     }
  388. #endif /* defined(HELIX_FEATURE_SMIL2). */
  389.     *ppvObj = NULL;
  390.     return HXR_NOINTERFACE;
  391. }
  392. /////////////////////////////////////////////////////////////////////////
  393. //  Method:
  394. // IUnknown::AddRef
  395. //  Purpose:
  396. // Everyone usually implements this the same... feel free to use
  397. // this implementation.
  398. //
  399. STDMETHODIMP_(ULONG32) CSmil1Renderer::AddRef()
  400. {
  401.     return InterlockedIncrement(&m_lRefCount);
  402. }
  403. /////////////////////////////////////////////////////////////////////////
  404. //  Method:
  405. // IUnknown::Release
  406. //  Purpose:
  407. // Everyone usually implements this the same... feel free to use
  408. // this implementation.
  409. //
  410. STDMETHODIMP_(ULONG32) CSmil1Renderer::Release()
  411. {
  412.     if (InterlockedDecrement(&m_lRefCount) > 0)
  413.     {
  414.         return m_lRefCount;
  415.     }
  416.     delete this;
  417.     return 0;
  418. }
  419. // *** IHXRenderer methods ***
  420. /////////////////////////////////////////////////////////////////////////
  421. //  Method:
  422. // IHXRenderer::StartStream
  423. //  Purpose:
  424. // Called by client engine to inform the renderer of the stream it
  425. // will be rendering. The stream interface can provide access to
  426. // its source or player. This method also provides access to the 
  427. // primary client controller interface.
  428. //
  429. STDMETHODIMP CSmil1Renderer::StartStream
  430. (
  431.     IHXStream*     pStream,
  432.     IHXPlayer*     pPlayer
  433. )
  434. {
  435. #if defined(HELIX_FEATURE_SMIL2)
  436.     m_bCSmil1StartStreamHasBeenCalled = TRUE;
  437.     HX_ASSERT(!m_bIsHigherVersionSmilStreamFromOldSMIL1FF);
  438. #endif /* defined(HELIX_FEATURE_SMIL2). */
  439.     HX_RESULT rc = HXR_OK;
  440.     // Save for later use!
  441.     m_pStream  = pStream;
  442.     m_pStream->AddRef();
  443.     m_pPlayer  = pPlayer;
  444.     m_pPlayer->AddRef();
  445.     m_pPlayer->GetClientEngine(m_pEngine);
  446.     m_pPlayer->GetClientContext(m_pClientContext);
  447.     IHXBuffer* pBuffer = NULL;
  448.     IHXPreferences* pPreferences = NULL;
  449.     IHXRendererAdviseSink* pRendererAdviseSink = NULL;
  450.     if (HXR_OK == m_pPlayer->QueryInterface(IID_IHXPreferences, (void**)&pPreferences))
  451.     {
  452. if (HXR_OK == pPreferences->ReadPref("useNestedMeta", pBuffer))
  453. {
  454.     m_bUseNestedMeta = atoi((const char*)pBuffer->GetBuffer()) ? TRUE : FALSE;
  455. }
  456. HX_RELEASE(pBuffer);
  457.     }
  458.     HX_RELEASE(pPreferences);
  459.     m_pSmilDocRenderer = new CSmil1DocumentRenderer(this, m_pContext);
  460.     m_pSmilDocRenderer->AddRef();
  461.     if (m_bUseNestedMeta)
  462.     {
  463. IHXPersistentComponent* pPersistentComponent = NULL;
  464. if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXPersistentComponentManager, 
  465.        (void**)&m_pPersistentComponentManager))
  466. {
  467.     m_pPersistentComponentManager->CreatePersistentComponent(pPersistentComponent);
  468.     pPersistentComponent->Init((IHXPersistentRenderer*)this);
  469.     pPersistentComponent->AddRendererAdviseSink((IHXRendererAdviseSink*)m_pSmilDocRenderer);
  470.     pPersistentComponent->AddGroupSink((IHXGroupSink*)m_pSmilDocRenderer);
  471.     rc = m_pPersistentComponentManager->AddPersistentComponent(pPersistentComponent);
  472.     generatePreFix();
  473. }
  474.     }
  475.     else
  476.     {
  477. IHXPersistenceManager* pMgr = 0;
  478. if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXPersistenceManager, 
  479.     (void**)&pMgr))
  480. {
  481.     IUnknown* pUnk = 0;
  482.     if(HXR_OK == pMgr->GetPersistentComponent(pUnk))
  483.     {
  484. rc = HXR_FAIL;
  485. CSmil1SMILSyntaxErrorHandler errHandler(m_pContext);
  486. errHandler.ReportError(SMILErrorMetaDatatype, NULL, 0);
  487. pUnk->Release();
  488.     }
  489.     else if(HXR_OK == QueryInterface(IID_IUnknown, (void**)&pUnk))
  490.     {
  491. pMgr->AddPersistentComponent(pUnk);
  492. pUnk->Release();
  493. generatePreFix();
  494.     }
  495.     pMgr->Release();
  496. }
  497. IHXDriverStreamManager* pDriverStreamMgr = 0;
  498. if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXDriverStreamManager,
  499.     (void**)&pDriverStreamMgr))
  500. {
  501.     if(HXR_OK == m_pSmilDocRenderer->QueryInterface(IID_IHXRendererAdviseSink, 
  502.     (void**)&pRendererAdviseSink))
  503.     {
  504. pDriverStreamMgr->AddRendererAdviseSink(pRendererAdviseSink);
  505. pRendererAdviseSink->Release();
  506.     }
  507.     pDriverStreamMgr->Release();
  508. }
  509. IHXGroupManager* pGrpMgr = 0;
  510. if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXGroupManager,
  511.     (void**)&pGrpMgr))
  512. {
  513.     IHXGroupSink* pSnk = 0;
  514.     if(HXR_OK == m_pSmilDocRenderer->QueryInterface(
  515. IID_IHXGroupSink, (void**)&pSnk))
  516.     {
  517. pGrpMgr->AddSink(pSnk);
  518. pSnk->Release();
  519.     }
  520. }
  521. HX_RELEASE(pGrpMgr);
  522.     }
  523.     return rc;
  524. }
  525. /////////////////////////////////////////////////////////////////////////
  526. //  Method:
  527. // IHXRenderer::EndStream
  528. //  Purpose:
  529. // Called by client engine to inform the renderer that the stream
  530. // is was rendering is closed.
  531. //
  532. STDMETHODIMP CSmil1Renderer::EndStream()
  533. {
  534. #if defined(HELIX_FEATURE_SMIL2)
  535.     m_bCSmil1EndStreamHasBeenCalled = TRUE;
  536. #endif /* defined(HELIX_FEATURE_SMIL2). */
  537.     if(m_pPlayer)
  538.     {
  539. if (m_bUseNestedMeta)
  540. {
  541.     IHXPersistentComponent* pPersistentComponent = NULL;
  542.     IHXRendererAdviseSink* pRendererAdviseSink = 0;
  543.     if (HXR_OK == m_pPersistentComponentManager->GetPersistentComponent(m_pSmilDocRenderer->m_ulPersistentComponentID,
  544. pPersistentComponent))
  545.     {
  546. pPersistentComponent->RemoveRendererAdviseSink((IHXRendererAdviseSink*)m_pSmilDocRenderer);
  547. pPersistentComponent->RemoveGroupSink((IHXGroupSink*)m_pSmilDocRenderer);
  548.     }
  549.     HX_RELEASE(pPersistentComponent);     
  550. }
  551. else
  552. {
  553.     IHXGroupManager* pGrpMgr = 0;
  554.     if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXGroupManager, 
  555. (void**)&pGrpMgr))
  556.     {
  557. IHXGroupSink* pSnk = 0;
  558. if(m_pSmilDocRenderer &&
  559.     HXR_OK == m_pSmilDocRenderer->QueryInterface(IID_IHXGroupSink, 
  560.     (void**)&pSnk))
  561. {
  562.     pGrpMgr->RemoveSink(pSnk);
  563.     pSnk->Release();
  564. }
  565. pGrpMgr->Release();
  566.     }
  567.     IHXDriverStreamManager* pStrmMgr = 0;
  568.     if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXDriverStreamManager,
  569. (void**)&pStrmMgr))
  570.     {
  571. IHXRendererAdviseSink* pSnk = 0;
  572. if(m_pSmilDocRenderer &&
  573.     HXR_OK == m_pSmilDocRenderer->QueryInterface(
  574.     IID_IHXRendererAdviseSink, (void**)&pSnk))
  575. {
  576.     pStrmMgr->RemoveRendererAdviseSink(pSnk);
  577.     pSnk->Release();
  578. }
  579. pStrmMgr->Release();
  580.     }
  581. }
  582.     }
  583.     HX_RELEASE(m_pStream);
  584. #if defined(HELIX_FEATURE_SMIL2)
  585.     if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
  586.     {
  587. if (!m_pNextGenSmilRenderer)
  588. {
  589.     return HXR_UNEXPECTED;
  590. }
  591. return m_pNextGenSmilRenderer->EndStream();
  592.     }
  593. #endif /* defined(HELIX_FEATURE_SMIL2). */
  594.     if(m_pSmilDocRenderer)
  595.     {
  596. m_pSmilDocRenderer->endStream();
  597.     }
  598.     return HXR_OK;
  599. }
  600. /////////////////////////////////////////////////////////////////////////
  601. //  Method:
  602. // IHXRenderer::OnHeader
  603. //  Purpose:
  604. // Called by client engine when a header for this renderer is 
  605. // available. The header will arrive before any packets.
  606. //
  607. STDMETHODIMP CSmil1Renderer::OnHeader(IHXValues* pHeader)
  608. {
  609.     // check stream and content versions so an upgrade can
  610.     // be called if necessary...
  611.     HX_RESULT rc = HXR_OK;
  612.     if (!pHeader)
  613.     {
  614. return HXR_UNEXPECTED;
  615.     }
  616. #if defined(HELIX_FEATURE_SMIL2)
  617.     // /Hang onto header in case we need to send it up to a higher-version
  618.     // SMIL renderer:
  619.     m_pHeader = pHeader;
  620.     m_pHeader->AddRef();
  621.     HX_ASSERT(!m_bIsHigherVersionSmilStreamFromOldSMIL1FF);
  622. #endif /* defined(HELIX_FEATURE_SMIL2). */
  623.     BOOL bVersionOK = TRUE;
  624.     UINT16 uGroupCount = 0;
  625.     UINT16 uCurrentGroupID = 0;
  626.     UINT16 uSupportedType = 0; // G2 style by default
  627.     UINT32 ulStreamVersion = 0;
  628.     UINT32 ulContentVersion = 0;
  629.     IHXGroupManager* pGrpMgr = NULL;
  630.     if(HXR_OK == pHeader->GetPropertyULONG32("StreamVersion", 
  631. ulStreamVersion))
  632.     {
  633. UINT32 ulMajorVersion = HX_GET_MAJOR_VERSION(ulStreamVersion);
  634. UINT32 ulMinorVersion = HX_GET_MINOR_VERSION(ulStreamVersion);
  635. if((ulMajorVersion > STREAM_MAJOR_VERSION) ||
  636.    (ulMinorVersion > STREAM_MINOR_VERSION &&
  637.     ulMajorVersion == STREAM_MAJOR_VERSION))
  638. {
  639.     bVersionOK = FALSE;
  640. }
  641.     }
  642.     if(bVersionOK &&
  643.        HXR_OK == pHeader->GetPropertyULONG32("ContentVersion",
  644.            ulContentVersion))
  645.     {
  646. UINT32 ulMajorVersion = HX_GET_MAJOR_VERSION(ulContentVersion);
  647. UINT32 ulMinorVersion = HX_GET_MINOR_VERSION(ulContentVersion);
  648. if((ulMajorVersion > CONTENT_MAJOR_VERSION) ||
  649.    (ulMinorVersion > CONTENT_MINOR_VERSION &&
  650.     ulMajorVersion == CONTENT_MAJOR_VERSION))
  651. {
  652.     bVersionOK = FALSE;
  653. }
  654.     }
  655.     if(!bVersionOK)
  656.     {
  657.         AddToAutoUpgradeCollection((const char*) zm_pStreamMimeTypes[0], m_pContext);
  658. rc = HXR_FAILED;
  659. goto cleanup;
  660.     }
  661.     m_pPacketParser = new CSmilPacketParser;
  662.     m_pSmilDocRenderer->onHeader(pHeader);     
  663.     if (m_bUseNestedMeta)
  664.     {
  665. if (!m_pSmilDocRenderer->IsNestedMetaSupported(uSupportedType))
  666. {
  667.     rc = HXR_INVALID_METAFILE;
  668.     goto cleanup;
  669. }
  670. switch (uSupportedType)
  671. {
  672. case 1:
  673.     // RP8 SS3 - limited SMIL in RAM support, blow-away all the existing groups
  674.     // when it is the last SMIL in RAM.
  675.     if (HXR_OK == m_pPlayer->QueryInterface(IID_IHXGroupManager, (void**)&pGrpMgr))
  676.     {
  677. uGroupCount = pGrpMgr->GetGroupCount();
  678. pGrpMgr->GetCurrentGroup(uCurrentGroupID);
  679. if ((uCurrentGroupID + 1) == uGroupCount)
  680. {
  681.     m_pSmilDocRenderer->m_bLastGroupInRAM20 = TRUE;
  682.     while(pGrpMgr && pGrpMgr->GetGroupCount() > 0)
  683.     {
  684. pGrpMgr->RemoveGroup(0);
  685.     }
  686. }
  687.     }
  688.     HX_RELEASE(pGrpMgr);
  689.     break;
  690. default:
  691.     break;
  692. }
  693.     }
  694.     else
  695.     {
  696. if (HXR_OK == m_pPlayer->QueryInterface(IID_IHXGroupManager, (void**)&pGrpMgr))
  697. {
  698.          while(pGrpMgr && pGrpMgr->GetGroupCount() > 0)
  699.     {
  700.         pGrpMgr->RemoveGroup(0);
  701.     }     
  702. }
  703. HX_RELEASE(pGrpMgr);
  704.     }
  705. cleanup:
  706.     return rc;
  707. }
  708. /////////////////////////////////////////////////////////////////////////
  709. //  Method:
  710. // IHXRenderer::OnPacket
  711. //  Purpose:
  712. // Called by client engine when a packet for this renderer is 
  713. // due.
  714. //
  715. STDMETHODIMP CSmil1Renderer::OnPacket(IHXPacket* pPacket, 
  716.  LONG32 lTimeOffset)
  717. {
  718.     HX_RESULT rc = HXR_OK;
  719.     IHXBuffer* pBuffer = NULL;
  720. #if defined(HELIX_FEATURE_SMIL2)
  721.     if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
  722.     {
  723. if (!m_pNextGenSmilRenderer)
  724. {
  725.     rc = HXR_UNEXPECTED;
  726.     goto cleanup;
  727. }
  728. rc = m_pNextGenSmilRenderer->OnPacket(pPacket, lTimeOffset);
  729.         goto cleanup;
  730.     }
  731. #endif /* defined(HELIX_FEATURE_SMIL2). */
  732.     HX_ASSERT(lTimeOffset <= 0);
  733.     m_pSmilDocRenderer->m_ulPersistentComponentDelay = -lTimeOffset;
  734.     //Fix for PR 23352: if we already returned a fail value from
  735.     // a prior OnPacket(), don't process this OnPacket():
  736.     if (HXR_OK != m_lastOnPacketResult)
  737.     {
  738. rc = m_lastOnPacketResult;
  739. goto cleanup;
  740.     }
  741.     pBuffer = pPacket->GetBuffer();
  742.     if(pBuffer)
  743.     {
  744. // /If parse() runs into a missing-quote situation,
  745. // we should stop and display an error.  Note that
  746. // CSmilPacketParser::parse(..)  does not keep track of
  747. // line numbers; TODO: add line-number counting to it.
  748. CSmilPacketParser::SMILPacketParseResult pktPrsRslt = CSmilPacketParser::SMILUnknown;
  749. CSmilPacket* pSmilPacket = m_pPacketParser->parse(
  750.     pBuffer, pktPrsRslt);
  751. if (CSmilPacketParser::SMILMissingQuote == pktPrsRslt)
  752. {
  753.     CSmil1SMILSyntaxErrorHandler errHandler(m_pContext);
  754.     errHandler.ReportError(SMILErrorBadAttribute,
  755.     "missing quote", 0);
  756. }
  757. else if(pSmilPacket)
  758. {
  759.     switch(pSmilPacket->m_type)
  760.     {
  761. case CSmilPacket::SMILDocument:
  762. {
  763. #if defined(HELIX_FEATURE_SMIL2)
  764.     if (!m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
  765.     {
  766. // /findSmilTagAndVersion returns TRUE if it finds
  767. // the <smil> tag, regardless of the presence of
  768. // a default namespace:
  769. if (HXR_OK == findSmilTagAndVersion(pBuffer))
  770. {
  771.     if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
  772.     {
  773. HX_RESULT pSUS2R = setUpNextGenSmilRenderer();
  774. if (HXR_OK!=pSUS2R  ||  !m_pNextGenSmilRenderer)
  775. {
  776.     rc = HXR_UNEXPECTED;
  777.     goto cleanup;
  778. }
  779.     }
  780. }
  781.     }
  782.     if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
  783.     {
  784. rc = m_pNextGenSmilRenderer->OnPacket(pPacket,
  785. lTimeOffset);
  786.     }
  787.     else
  788. #endif /* defined(HELIX_FEATURE_SMIL2). */
  789.     {
  790. rc = handleSMILDocumentPacket(
  791.     (CSmilDocumentPacket*)pSmilPacket);
  792.     }
  793.     if (HXR_OK != rc)
  794.     {
  795. m_lastOnPacketResult = rc;
  796.     }
  797. }
  798. break;
  799. default:
  800. break;
  801.     }
  802.     delete pSmilPacket;
  803. }
  804. HX_RELEASE(pBuffer);
  805.     }
  806. cleanup:
  807.     return rc;
  808. }
  809. /////////////////////////////////////////////////////////////////////////
  810. //  Method:
  811. // IHXRenderer::OnTimeSync
  812. //  Purpose:
  813. // Called by client engine to inform the renderer of the current
  814. // time relative to the streams synchronized time-line. The 
  815. // renderer should use this time value to update its display or
  816. // render it's stream data accordingly.
  817. //
  818. STDMETHODIMP CSmil1Renderer::OnTimeSync(ULONG32 ulTime)
  819. {
  820.     HX_RESULT rc = HXR_OK;
  821. #if defined(HELIX_FEATURE_SMIL2)
  822.     if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
  823.     {
  824. if (!m_pNextGenSmilRenderer)
  825. {
  826.     rc = HXR_UNEXPECTED;
  827.     goto cleanup;
  828. }
  829. rc = m_pNextGenSmilRenderer->OnTimeSync(ulTime);
  830.         goto cleanup;
  831.     }
  832. #endif /* defined(HELIX_FEATURE_SMIL2). */
  833.     if(m_pSmilDocRenderer)
  834.     {
  835. rc = m_pSmilDocRenderer->onTimeSync(ulTime);
  836.     }
  837. #if defined(HELIX_FEATURE_SMIL2)
  838. cleanup:
  839. #endif /* defined(HELIX_FEATURE_SMIL2). */
  840.     return rc;
  841. }
  842. /////////////////////////////////////////////////////////////////////////
  843. //  Method:
  844. // IHXRenderer::OnPreSeek
  845. //  Purpose:
  846. // Called by client engine to inform the renderer that a seek is
  847. // about to occur. The render is informed the last time for the 
  848. // stream's time line before the seek, as well as the first new
  849. // time for the stream's time line after the seek will be completed.
  850. //
  851. STDMETHODIMP CSmil1Renderer::OnPreSeek(ULONG32 ulOldTime, ULONG32 ulNewTime)
  852. {
  853.     HX_RESULT rc = HXR_OK;
  854. #if defined(HELIX_FEATURE_SMIL2)
  855.     if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
  856.     {
  857. if (!m_pNextGenSmilRenderer)
  858. {
  859.     rc = HXR_UNEXPECTED;
  860.     goto cleanup;
  861. }
  862. rc = m_pNextGenSmilRenderer->OnPreSeek(ulOldTime, ulNewTime);
  863.         goto cleanup;
  864.     }
  865. #endif /* defined(HELIX_FEATURE_SMIL2). */
  866.     if(m_pSmilDocRenderer)
  867.     {
  868. rc = m_pSmilDocRenderer->onPreSeek(ulOldTime, ulNewTime);
  869.     }
  870. #if defined(HELIX_FEATURE_SMIL2)
  871. cleanup:
  872. #endif /* defined(HELIX_FEATURE_SMIL2). */
  873.     return rc;
  874. }
  875. /////////////////////////////////////////////////////////////////////////
  876. //  Method:
  877. // IHXRenderer::OnPostSeek
  878. //  Purpose:
  879. // Called by client engine to inform the renderer that a seek has
  880. // just occured. The render is informed the last time for the 
  881. // stream's time line before the seek, as well as the first new
  882. // time for the stream's time line after the seek.
  883. //
  884. STDMETHODIMP CSmil1Renderer::OnPostSeek(ULONG32 ulOldTime,
  885.    ULONG32 ulNewTime)
  886. {
  887.     HX_RESULT rc = HXR_OK;
  888. #if defined(HELIX_FEATURE_SMIL2)
  889.     if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
  890.     {
  891. if (!m_pNextGenSmilRenderer)
  892. {
  893.     rc = HXR_UNEXPECTED;
  894.     goto cleanup;
  895. }
  896. rc = m_pNextGenSmilRenderer->OnPostSeek(ulOldTime, ulNewTime);
  897.         goto cleanup;
  898.     }
  899. #endif /* defined(HELIX_FEATURE_SMIL2). */
  900. #if defined(HELIX_FEATURE_SMIL2)
  901. cleanup:
  902. #endif /* defined(HELIX_FEATURE_SMIL2). */
  903.     return rc;
  904. }
  905. /////////////////////////////////////////////////////////////////////////
  906. //  Method:
  907. // IHXRenderer::OnPause
  908. //  Purpose:
  909. // Called by client engine to inform the renderer that a pause has
  910. // just occured. The render is informed the last time for the 
  911. // stream's time line before the pause.
  912. //
  913. STDMETHODIMP CSmil1Renderer::OnPause(ULONG32 ulTime)
  914. {
  915.     HX_RESULT rc = HXR_OK;
  916. #if defined(HELIX_FEATURE_SMIL2)
  917.     if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
  918.     {
  919. if (!m_pNextGenSmilRenderer)
  920. {
  921.     rc = HXR_UNEXPECTED;
  922.     goto cleanup;
  923. }
  924. rc = m_pNextGenSmilRenderer->OnPause(ulTime);
  925.         goto cleanup;
  926.     }
  927. #endif /* defined(HELIX_FEATURE_SMIL2). */
  928. #if defined(HELIX_FEATURE_SMIL2)
  929. cleanup:
  930. #endif /* defined(HELIX_FEATURE_SMIL2). */
  931.     return rc;
  932. }
  933. /////////////////////////////////////////////////////////////////////////
  934. //  Method:
  935. // IHXRenderer::OnBegin
  936. //  Purpose:
  937. // Called by client engine to inform the renderer that a begin or
  938. // resume has just occured. The render is informed the first time 
  939. // for the stream's time line after the resume.
  940. //
  941. STDMETHODIMP CSmil1Renderer::OnBegin(ULONG32 ulTime)
  942. {
  943.     HX_RESULT rc = HXR_OK;
  944. #if defined(HELIX_FEATURE_SMIL2)
  945.     if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
  946.     {
  947. if (!m_pNextGenSmilRenderer)
  948. {
  949.     rc = HXR_UNEXPECTED;
  950.     goto cleanup;
  951. }
  952. rc = m_pNextGenSmilRenderer->OnBegin(ulTime);
  953.         goto cleanup;
  954.     }
  955. #endif /* defined(HELIX_FEATURE_SMIL2). */
  956. #if defined(HELIX_FEATURE_SMIL2)
  957. cleanup:
  958. #endif /* defined(HELIX_FEATURE_SMIL2). */
  959.     return rc;
  960. }
  961. /////////////////////////////////////////////////////////////////////////
  962. //  Method:
  963. // IHXRenderer::OnBuffering
  964. //  Purpose:
  965. // Called by client engine to inform the renderer that buffering
  966. // of data is occuring. The render is informed of the reason for
  967. // the buffering (start-up of stream, seek has occured, network
  968. // congestion, etc.), as well as percentage complete of the 
  969. // buffering process.
  970. //
  971. STDMETHODIMP CSmil1Renderer::OnBuffering(ULONG32 ulFlags,
  972. UINT16 unPercentComplete)
  973. {
  974.     HX_RESULT rc = HXR_OK;
  975. #if defined(HELIX_FEATURE_SMIL2)
  976.     if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
  977.     {
  978. if (!m_pNextGenSmilRenderer)
  979. {
  980.     rc = HXR_UNEXPECTED;
  981.     goto cleanup;
  982. }
  983. rc = m_pNextGenSmilRenderer->OnBuffering(ulFlags,
  984. unPercentComplete);
  985.         goto cleanup;
  986.     }
  987. #endif /* defined(HELIX_FEATURE_SMIL2). */
  988. #if defined(HELIX_FEATURE_SMIL2)
  989. cleanup:
  990. #endif /* defined(HELIX_FEATURE_SMIL2). */
  991.     return rc;
  992. }
  993. /////////////////////////////////////////////////////////////////////////
  994. //  Method:
  995. // IHXRenderer::GetDisplayType
  996. //  Purpose:
  997. // Called by client engine to ask the renderer for it's preferred
  998. // display type. When layout information is not present, the 
  999. // renderer will be asked for it's prefered display type. Depending
  1000. // on the display type a buffer of additional information may be 
  1001. // needed. This buffer could contain information about preferred
  1002. // window size.
  1003. //
  1004. STDMETHODIMP CSmil1Renderer::GetDisplayType
  1005. (
  1006.     REF(HX_DISPLAY_TYPE)   ulFlags,
  1007.     REF(IHXBuffer*)     pBuffer
  1008. )
  1009. {
  1010.     HX_RESULT rc = HXR_OK;
  1011.     ulFlags = HX_DISPLAY_NONE;
  1012. #if defined(HELIX_FEATURE_SMIL2)
  1013.     m_bCSmil1GetDisplayTypeHasBeenCalled = TRUE;
  1014.     if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
  1015.     {
  1016. if (!m_pNextGenSmilRenderer)
  1017. {
  1018.     rc = HXR_UNEXPECTED;
  1019.     goto cleanup;
  1020. }
  1021. rc = m_pNextGenSmilRenderer->GetDisplayType(ulFlags,
  1022. pBuffer);
  1023.         goto cleanup;
  1024.     }
  1025. #endif /* defined(HELIX_FEATURE_SMIL2). */
  1026. #if defined(HELIX_FEATURE_SMIL2)
  1027. cleanup:
  1028. #endif /* defined(HELIX_FEATURE_SMIL2). */
  1029.     return rc;
  1030. }
  1031. /************************************************************************
  1032.  * Method:
  1033.  *     IHXRenderer::OnEndofPackets
  1034.  * Purpose:
  1035.  *     Called by client engine to inform the renderer that all the
  1036.  *     packets have been delivered. However, if the user seeks before
  1037.  *     EndStream() is called, renderer may start getting packets again
  1038.  *     and the client engine will eventually call this function again.
  1039.  */
  1040. STDMETHODIMP CSmil1Renderer::OnEndofPackets(void)
  1041. {
  1042.     HX_RESULT rc = HXR_OK;
  1043. #if defined(HELIX_FEATURE_SMIL2)
  1044.     if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
  1045.     {
  1046. if (!m_pNextGenSmilRenderer)
  1047. {
  1048.     rc = HXR_UNEXPECTED;
  1049.     goto cleanup;
  1050. }
  1051. rc = m_pNextGenSmilRenderer->OnEndofPackets();
  1052.         goto cleanup;
  1053.     }
  1054. #endif /* defined(HELIX_FEATURE_SMIL2). */
  1055. #if defined(HELIX_FEATURE_SMIL2)
  1056. cleanup:
  1057. #endif /* defined(HELIX_FEATURE_SMIL2). */
  1058.     return rc;
  1059. }
  1060. /************************************************************************
  1061.  * Method:
  1062.  *     IHXStatistics::Init
  1063.  * Purpose:
  1064.  *     Pass registry ID to the caller
  1065.  *
  1066.  */
  1067. STDMETHODIMP
  1068. CSmil1Renderer::InitializeStatistics
  1069. (
  1070.     UINT32 /*IN*/ ulRegistryID
  1071. )
  1072. {
  1073.     HX_RESULT rc = HXR_OK;
  1074.     IHXRegistry* pRegistry = NULL;
  1075. #if defined(HELIX_FEATURE_SMIL2)
  1076.     m_ulRegistryID = ulRegistryID;
  1077.     m_bCSmil1InitializeStatisticsHasBeenCalled = TRUE;
  1078.     if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
  1079.     {
  1080. if (!m_pNextGenSmilRenderer)
  1081. {
  1082.     rc = HXR_UNEXPECTED;
  1083.     goto cleanup;
  1084. }
  1085. rc = m_pNextGenSmilRenderer->InitializeStatistics(m_ulRegistryID);
  1086.         goto cleanup;
  1087.     }
  1088. #endif /* defined(HELIX_FEATURE_SMIL2). */
  1089.     if (m_pContext &&
  1090. HXR_OK == m_pContext->QueryInterface(IID_IHXRegistry, (void**)&pRegistry))
  1091.     {
  1092. char     szRegistryEntry[MAX_DISPLAY_NAME] = {0}; /* Flawfinder: ignore */
  1093. IHXBuffer*     pszRegistryName = NULL;
  1094. // Get the current registry key name
  1095. if (HXR_OK == pRegistry->GetPropName(ulRegistryID, pszRegistryName))
  1096. {
  1097.     IHXBuffer* pValue = new CHXBuffer();
  1098.     pValue->AddRef();
  1099.     SafeSprintf(szRegistryEntry, MAX_DISPLAY_NAME, "%s.name", pszRegistryName->GetBuffer());
  1100.     pValue->Set((const UCHAR*)zm_pName, strlen((const char*) zm_pName) + 1);
  1101.     pRegistry->AddStr(szRegistryEntry, pValue);
  1102.     HX_RELEASE(pValue);
  1103.     HX_RELEASE(pszRegistryName);
  1104. }
  1105. HX_RELEASE(pRegistry);
  1106.     }
  1107. #if defined(HELIX_FEATURE_SMIL2)
  1108. cleanup:
  1109. #endif /* defined(HELIX_FEATURE_SMIL2). */
  1110.     return rc;
  1111. }
  1112. /************************************************************************
  1113.  * Method:
  1114.  *     IHXStatistics::Update
  1115.  * Purpose:
  1116.  *     Notify the client to update its statistics stored in the registry
  1117.  *
  1118.  */
  1119. STDMETHODIMP 
  1120. CSmil1Renderer::UpdateStatistics()
  1121. {
  1122.     HX_RESULT rc = HXR_OK;
  1123. #if defined(HELIX_FEATURE_SMIL2)
  1124.     if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
  1125.     {
  1126. if (!m_pNextGenSmilRenderer)
  1127. {
  1128.     rc = HXR_UNEXPECTED;
  1129.     goto cleanup;
  1130. }
  1131. rc = m_pNextGenSmilRenderer->UpdateStatistics();
  1132.         goto cleanup;
  1133.     }
  1134. #endif /* defined(HELIX_FEATURE_SMIL2). */
  1135. #if defined(HELIX_FEATURE_SMIL2)
  1136. cleanup:
  1137. #endif /* defined(HELIX_FEATURE_SMIL2). */
  1138.     return rc;
  1139. }
  1140. // IHXPersistentRenderer methods
  1141. STDMETHODIMP
  1142. CSmil1Renderer::InitPersistent(UINT32 ulPersistentComponentID,
  1143.      UINT16 uPersistentGroupID,
  1144.      UINT16 uPersistentTrackID,
  1145.      IHXPersistentRenderer* pPersistentParent)
  1146. {
  1147.     HX_RESULT rc = HXR_OK;
  1148.     m_ulPersistentComponentID = ulPersistentComponentID;
  1149.     m_uPersistentGroupID = uPersistentGroupID;
  1150.     m_uPersistentTrackID = uPersistentTrackID;
  1151.     m_pPersistentParent = pPersistentParent;
  1152.     if (m_pPersistentParent)
  1153.     {
  1154. m_pPersistentParent->AddRef();
  1155.     }
  1156. #if defined(HELIX_FEATURE_SMIL2)
  1157. #if defined(DO_INIT_PERSISTENT_ON_NEXTGEN_SMILREND)
  1158.     m_bCSmil1InitPersistenHasBeenCalled = TRUE;
  1159.     HX_ASSERT (!m_bIsHigherVersionSmilStreamFromOldSMIL1FF);
  1160. #endif
  1161. #endif /* defined(HELIX_FEATURE_SMIL2). */
  1162.     rc = m_pSmilDocRenderer->InitPersistent(ulPersistentComponentID,
  1163.       uPersistentGroupID,
  1164.       uPersistentTrackID,
  1165.       pPersistentParent);
  1166.     return rc;
  1167. }
  1168. STDMETHODIMP
  1169. CSmil1Renderer::GetPersistentID(REF(UINT32) ulPersistentComponentID)
  1170. {
  1171.     HX_RESULT rc = HXR_OK;
  1172.     ulPersistentComponentID = m_pSmilDocRenderer->m_ulPersistentComponentID;
  1173.     return rc;
  1174. }
  1175. STDMETHODIMP
  1176. CSmil1Renderer::GetPersistentProperties(REF(IHXValues*) pProperties)
  1177. {
  1178.     HX_RESULT rc = HXR_OK;
  1179.     pProperties = new CHXHeader();
  1180.     pProperties->AddRef();
  1181.     pProperties->SetPropertyULONG32("PersistentType", m_persistentType);
  1182.     pProperties->SetPropertyULONG32("PersistentVersion", m_ulPersistentVersion);
  1183.     return rc;
  1184. }
  1185. STDMETHODIMP
  1186. CSmil1Renderer::GetElementProperties(UINT16 uGroupID,
  1187.     UINT16 uTrackID,
  1188.                                     REF(IHXValues*) pProperties)
  1189. {
  1190.     HX_RESULT rc = HXR_OK;
  1191. #if defined(HELIX_FEATURE_SMIL2)
  1192.     m_bCSmil1GetElementPropertiesHasBeenCalled = TRUE;
  1193.     m_uGroupID = uGroupID;
  1194.     m_uTrackID = uTrackID;
  1195.     if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
  1196.     {
  1197. if (!m_pNextGenSmilRenderer)
  1198. {
  1199.     rc = HXR_UNEXPECTED;
  1200.     goto cleanup;
  1201. }
  1202. rc = m_pNextGenSmilRenderer->GetElementProperties(
  1203. uGroupID, uTrackID, pProperties);
  1204. HX_ASSERT(0  &&  "XXXEH- call on both sm1 and sm2 rends?");
  1205.     }
  1206. #endif /* defined(HELIX_FEATURE_SMIL2). */
  1207.     rc = m_pSmilDocRenderer->GetElementProperties(uGroupID,
  1208.     uTrackID,
  1209.     pProperties);
  1210. #if defined(HELIX_FEATURE_SMIL2)
  1211. cleanup:
  1212. #endif /* defined(HELIX_FEATURE_SMIL2). */
  1213.     return rc;
  1214. }
  1215. STDMETHODIMP
  1216. CSmil1Renderer::AttachElementLayout(UINT16     uGroupID,
  1217.     UINT16     uTrackID,
  1218.     IHXRenderer*   pRenderer,
  1219.     IHXStream*     pStream,
  1220.     IHXValues*     pProps)
  1221. {
  1222.     HX_RESULT rc = HXR_OK;
  1223. #if defined(HELIX_FEATURE_SMIL2)
  1224.     if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
  1225.     {
  1226. if (!m_pNextGenSmilRenderer)
  1227. {
  1228.     rc = HXR_UNEXPECTED;
  1229.     goto cleanup;
  1230. }
  1231. rc = m_pNextGenSmilRenderer->AttachElementLayout(uGroupID,
  1232.  uTrackID,
  1233.  pRenderer,
  1234.  pStream,
  1235.  pProps);
  1236. HX_ASSERT(0  &&  "XXXEH- call on both sm1 and sm2 rends?");
  1237.     }
  1238. #endif /* defined(HELIX_FEATURE_SMIL2). */
  1239.     rc = m_pSmilDocRenderer->AttachElementLayout(uGroupID, 
  1240.  uTrackID,
  1241.  pRenderer,
  1242.  pStream,
  1243.  pProps);
  1244. #if defined(HELIX_FEATURE_SMIL2)
  1245. cleanup:
  1246. #endif /* defined(HELIX_FEATURE_SMIL2). */
  1247.     return rc;
  1248. }
  1249. STDMETHODIMP
  1250. CSmil1Renderer::DetachElementLayout(IUnknown* pLSG)
  1251. {
  1252.     HX_RESULT rc = HXR_OK;
  1253. #if defined(HELIX_FEATURE_SMIL2)
  1254.     m_bCSmil1RemoveLayoutSiteGroupHasBeenCalled = TRUE;
  1255.     if (m_bIsHigherVersionSmilStreamFromOldSMIL1FF)
  1256.     {
  1257. if (!m_pNextGenSmilRenderer)
  1258. {
  1259.     rc = HXR_UNEXPECTED;
  1260.     goto cleanup;
  1261. }
  1262. rc = m_pNextGenSmilRenderer->DetachElementLayout(pLSG);
  1263. HX_ASSERT(0  &&  "XXXEH- call on both sm1 and sm2 rends?");
  1264.     }
  1265. #endif /* defined(HELIX_FEATURE_SMIL2). */
  1266.     rc = m_pSmilDocRenderer->DetachElementLayout(pLSG);
  1267. #if defined(HELIX_FEATURE_SMIL2)
  1268. cleanup:
  1269. #endif /* defined(HELIX_FEATURE_SMIL2). */
  1270.     return rc;
  1271. }
  1272. STDMETHODIMP
  1273. CSmil1Renderer::GetElementStatus(UINT16     uGroupID,
  1274. UINT16     uTrackID,
  1275. UINT32     ulCurrentTime,
  1276. REF(IHXValues*)    pStatus)
  1277. {
  1278.     return m_pSmilDocRenderer->GetElementStatus(uGroupID,
  1279. uTrackID,
  1280. ulCurrentTime,
  1281. pStatus);
  1282. }
  1283. HX_RESULT
  1284. CSmil1Renderer::HandleAddLayoutSiteGroup(IUnknown* pLSG)
  1285. {
  1286.     HX_RESULT     rc = HXR_OK;
  1287.     IHXValues*     pProps = NULL;
  1288.     IHXPersistentRenderer* pPersistentParentRenderer = NULL;
  1289.     pPersistentParentRenderer = m_pSmilDocRenderer->m_pPersistentParentRenderer;
  1290.     // nested meta, get layout from its parent
  1291.     if (pPersistentParentRenderer)
  1292.     {
  1293. pProps = new CHXHeader();
  1294. if (pProps)
  1295. {
  1296.     pProps->AddRef();
  1297.     pProps->SetPropertyULONG32("PersistentType", m_persistentType);
  1298. }
  1299. rc = pPersistentParentRenderer->AttachElementLayout(m_pSmilDocRenderer->m_uPersistentGroupID,
  1300.     m_pSmilDocRenderer->m_uPersistentTrackID,
  1301.     (IHXRenderer*)pLSG,
  1302.     NULL,
  1303.     pProps);
  1304.     }
  1305.     else if (m_pPlayer)
  1306.     {
  1307. IHXLayoutSiteGroupManager* pLSGMgr = 0;
  1308. if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXLayoutSiteGroupManager, (void**)&pLSGMgr))
  1309. {
  1310.     rc = pLSGMgr->AddLayoutSiteGroup(pLSG);
  1311.     pLSGMgr->Release();
  1312. }
  1313.     }
  1314.     HX_RELEASE(pProps);
  1315.     return rc;
  1316. }
  1317. HX_RESULT
  1318. CSmil1Renderer::HandleRemoveLayoutSiteGroup(IUnknown* pLSG)
  1319. {
  1320.     HX_RESULT     rc = HXR_OK;
  1321.     IHXPersistentRenderer* pPersistentParentRenderer = NULL;
  1322.     pPersistentParentRenderer = m_pSmilDocRenderer->m_pPersistentParentRenderer;
  1323.     // nested meta, remove layout from its parent
  1324.     if (pPersistentParentRenderer)
  1325.     {
  1326. rc = pPersistentParentRenderer->DetachElementLayout(pLSG);
  1327.     }
  1328.     else if (m_pPlayer)
  1329.     {
  1330. IHXLayoutSiteGroupManager* pLSGMgr = 0;
  1331. if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXLayoutSiteGroupManager, (void**)&pLSGMgr))
  1332. {
  1333.     rc = pLSGMgr->RemoveLayoutSiteGroup(pLSG);
  1334.     pLSGMgr->Release();
  1335. }
  1336.     }
  1337.     return rc;
  1338. }
  1339. HX_RESULT
  1340. CSmil1Renderer::HandleAttachElementLayout(IUnknown* pLSG, IHXValues* pProps)
  1341. {
  1342.     HX_RESULT rc = HXR_OK;
  1343.     if (m_pPersistentComponentManager)
  1344.     {
  1345. rc = m_pPersistentComponentManager->AttachPersistentComponentLayout(pLSG, pProps);
  1346.     }
  1347.     return rc;
  1348. }
  1349. HX_RESULT
  1350. CSmil1Renderer::handleSMILDocumentPacket(CSmilDocumentPacket* pPacket)
  1351. {
  1352.     HX_RESULT rc = HXR_OK;
  1353.     if(pPacket->m_version == RMA_DRIVER_VERSION)
  1354.     {
  1355. CHXBuffer* pBuffer = new CHXBuffer;
  1356. pBuffer->AddRef();
  1357. BOOL bLastPacket = FALSE;
  1358. UINT32 ulDocLen = (UINT32)pPacket->m_document.GetLength();
  1359. HX_ASSERT(ulDocLen);
  1360. // /Extra safety check:
  1361. if (0 == ulDocLen)
  1362. {
  1363.     rc = HXR_UNEXPECTED;
  1364.     bLastPacket = FALSE;
  1365. }
  1366. else
  1367. {
  1368.     pBuffer->Set((const BYTE*)(const char*)pPacket->m_document,
  1369.     pPacket->m_document.GetLength());
  1370.     m_ulTotalSMILPackets++;
  1371.     bLastPacket = pPacket->m_ulTotalPackets == m_ulTotalSMILPackets;
  1372.     rc = m_pSmilDocRenderer->onPacket(pBuffer, bLastPacket);
  1373. }
  1374. HX_RELEASE(pBuffer);
  1375. if(HXR_OK != rc)
  1376. {
  1377.     // XML parsing error
  1378.     UINT32 ulLineNumber = 0;
  1379.     UINT32 ulColumnNumber = 0;
  1380.     IHXBuffer* pErrorText = NULL;
  1381.     m_pSmilDocRenderer->getErrorInfo(ulLineNumber,
  1382. ulColumnNumber, pErrorText);
  1383.     const char* pActualErrorText = NULL;
  1384.     if(pErrorText)
  1385.     {
  1386. pActualErrorText = (const char*)pErrorText->GetBuffer();
  1387.     }
  1388.     CSmil1XMLSyntaxErrorHandler errHandler(m_pContext);
  1389.     errHandler.ReportError(rc, pActualErrorText, ulLineNumber);
  1390.     HX_RELEASE(pErrorText);
  1391. }
  1392. else if(bLastPacket)
  1393. {
  1394.     //[SMIL 1.0 compliance] Handle error from setDocument()
  1395.     // otherwise it "plays" (nothing for 20 seconds) when it
  1396.     // should halt under error conditions:
  1397.     rc = m_pSmilDocRenderer->setDocument(m_pURLFragment);
  1398. }
  1399.     }
  1400.     return rc;
  1401. }
  1402. void
  1403. CSmil1Renderer::generatePreFix()
  1404. {
  1405.     // get the protocol/server for later...
  1406.     IHXStreamSource* pSource = 0;
  1407.     m_pStream->GetSource(pSource);
  1408.     HX_ASSERT(pSource);
  1409.     if (!pSource)
  1410.     {
  1411. return;
  1412.     }
  1413.     const char* pURL = pSource->GetURL();
  1414.     HX_ASSERT(pURL);
  1415.     
  1416.     if (!pURL)
  1417.     {
  1418. return;
  1419.     }
  1420.     CHXURL::GeneratePrefixRootFragment(pURL, m_urlPrefix, m_urlRoot, m_pURLFragment);
  1421.     HX_RELEASE(pSource);
  1422.     return;
  1423. }
  1424. #if defined(HELIX_FEATURE_SMIL2)
  1425. HX_RESULT 
  1426. CSmil1Renderer::findValidDefaultNamespace(IHXBuffer* pStartOfFile)
  1427. {
  1428.     HX_RESULT pnreslt = HXR_OK;
  1429.     const char* pSmilTag = NULL;
  1430.     const char* pCloseOfSmilTag = NULL;
  1431.     const char* pXmlns = NULL;
  1432.     const char* pXmlnsOpenQuotationMark = NULL;
  1433.     const char* pBuf = NULL;
  1434.     ULONG32 ulBufLen = 0;
  1435.     const char* pEqualsSign = NULL;
  1436.     const char* pTmp = NULL;
  1437.     char* pTmp2 = NULL;
  1438.     char* pszStartOfFile = NULL;
  1439.     ULONG32 ulCount = 0;
  1440.     LONG32 lNumCommentsOpen = 0;
  1441.     if (!pStartOfFile)
  1442.     {
  1443. pnreslt = HXR_BUFFERTOOSMALL;
  1444. goto cleanup;
  1445.     }
  1446.     // /Fixes PR 59282: pStartOfFile is not necessarily NULL-terminated,
  1447.     // so we have to limit our access of it to the size of the buffer:
  1448.     ulBufLen = pStartOfFile->GetSize();
  1449.     pBuf = (const char*)pStartOfFile->GetBuffer();
  1450.     if (!pBuf  ||  !ulBufLen)
  1451.     {
  1452. pnreslt = HXR_BUFFERTOOSMALL;
  1453. goto cleanup;
  1454.     }
  1455.     pszStartOfFile = new char[ulBufLen+1];
  1456.     if (!pszStartOfFile)
  1457.     {
  1458. pnreslt = HXR_OUTOFMEMORY;
  1459. goto cleanup;
  1460.     }
  1461.     // /Now, walk through and copy each character from non-NULL terminated buf:
  1462.     pTmp = pBuf; 
  1463.     pTmp2 = pszStartOfFile;
  1464.     while (*pTmp  &&  ulCount<ulBufLen)
  1465.     {
  1466. *pTmp2 = *pTmp;
  1467. pTmp++;
  1468. pTmp2++;
  1469. ulCount++;
  1470.     }
  1471.     pszStartOfFile[ulCount] = ''; // /NULL-terminate it.
  1472.     // /Now, let's walk through the start of pszStartOfFile looking for
  1473.     // namespace declaration(s) inside the <smil ...> tag, and make sure that
  1474.     // the smil tag is NOT inside of a comment:
  1475.     pTmp = pszStartOfFile;
  1476.     while (*pTmp)
  1477.     {
  1478. if (0==strncmp(pTmp, "<!--", 4) )
  1479. {
  1480.     lNumCommentsOpen++;
  1481.     pTmp+=4;
  1482. }
  1483. else if (0==strncmp(pTmp, "-->", 3) )
  1484. {
  1485.     lNumCommentsOpen--;
  1486.     pTmp+=3;
  1487. }
  1488. else if (lNumCommentsOpen<=0  &&  0==strncmp(pTmp, "<smil", 5) )
  1489. {
  1490.     pSmilTag = pTmp; // /We found the smil tag outside of a comment.
  1491.     break;
  1492. }
  1493. else
  1494. {
  1495.     pTmp++;
  1496. }
  1497.     }
  1498.     if (!pSmilTag  ||  ulBufLen-(pSmilTag-pszStartOfFile) < 6) // /6==min size: "<smil>"
  1499.     {
  1500. // /There had better be a <smil...> tag!
  1501. pnreslt = HXR_UNEXPECTED;
  1502. goto cleanup;
  1503.     }
  1504.     pCloseOfSmilTag = strchr(pSmilTag, '>');
  1505.     // /Add 6 so that we don't allow "<smilxmlns ..." (which is invalid):
  1506.     pXmlns = strstr(pSmilTag+6, "xmlns");
  1507.     if (pXmlns  &&  isspace(*(pXmlns-1)) ) // /"xmlns" must follow a space.
  1508.     {
  1509. pEqualsSign = strchr(pXmlns, '=');
  1510. if (pEqualsSign)
  1511. {
  1512.     pXmlnsOpenQuotationMark = strchr(pXmlns, '"');
  1513. }
  1514.     }
  1515.     if (pXmlns  &&   pEqualsSign  &&  pXmlnsOpenQuotationMark  &&
  1516.     (!pCloseOfSmilTag  ||  pXmlns<pCloseOfSmilTag))
  1517.     {
  1518. m_bIsHigherVersionSmilStreamFromOldSMIL1FF = TRUE;
  1519. // /First, make sure there is nothing but whitespace between
  1520. // the "xmlns" and the '=' as well as between the '=' and the
  1521. // quotation mark:
  1522. char* pTmp = (char*)(pXmlns + strlen("xmlns"));
  1523. while (pTmp<pEqualsSign)
  1524. {
  1525.     if (!isspace(*pTmp))
  1526.     {
  1527. m_bIsHigherVersionSmilStreamFromOldSMIL1FF = FALSE;
  1528. break;
  1529.     }
  1530.     pTmp++;
  1531. }
  1532. pTmp = (char*)(pEqualsSign+1);
  1533. while(pTmp<pXmlnsOpenQuotationMark)
  1534. {
  1535.     if (!isspace(*pTmp)  &&  *pTmp != '\')
  1536.     {
  1537. m_bIsHigherVersionSmilStreamFromOldSMIL1FF = FALSE;
  1538. break;
  1539.     }
  1540.     pTmp++;
  1541. }
  1542. char* pDefaultNamespace = (char*)pXmlnsOpenQuotationMark+1;
  1543. if (strlen(pDefaultNamespace) > 0)
  1544. {
  1545.     char* pXmlnsCloseQuotationMark = strstr(pDefaultNamespace, "\"");
  1546.     if (pXmlnsCloseQuotationMark)
  1547.     {
  1548. *pXmlnsCloseQuotationMark = ''; // /NULL-terminate it.
  1549.     }
  1550.     else
  1551.     {
  1552. HX_ASSERT(pXmlnsCloseQuotationMark);
  1553. pnreslt = HXR_FAIL;
  1554. goto cleanup;
  1555.     }
  1556. }
  1557. HX_RELEASE(m_pDefaultNamespace);
  1558. if (m_pCommonClassFactory  &&
  1559. HXR_OK == m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer,
  1560. (void**)&m_pDefaultNamespace) )
  1561. {
  1562.     LONG32 lLen = strlen(pDefaultNamespace);
  1563.     if (lLen > 0  &&  lLen < 10000) // /sanity check
  1564.     {
  1565. m_pDefaultNamespace->Set((const BYTE*)pDefaultNamespace,
  1566.         lLen + 1);
  1567.     }
  1568.     pnreslt = HXR_OK;
  1569. }
  1570.     }
  1571. cleanup:
  1572.     if (pszStartOfFile)
  1573.     {
  1574. HX_VECTOR_DELETE(pszStartOfFile);
  1575.     }
  1576.     return pnreslt;
  1577. }
  1578. #endif /* defined(HELIX_FEATURE_SMIL2). */
  1579. #if defined(HELIX_FEATURE_SMIL2)
  1580. // /The following two methods are used for looking for and handling SMIL 2+
  1581. // streams coming from SMIL 1.0 File Format plugins (that didn't have smarts
  1582. // to look for default namespace which identifies the SMIL file version):
  1583. HX_RESULT
  1584. CSmil1Renderer::findSmilTagAndVersion(IHXBuffer* pFileChunk)
  1585. {
  1586.     HX_RESULT rc = HXR_OK;
  1587.     ULONG32 ulLen = 0;
  1588.     if (!pFileChunk  ||  (ulLen=pFileChunk->GetSize()) < 6)
  1589.     {
  1590. rc = HXR_FAILED;
  1591. goto cleanup;
  1592.     }
  1593.     rc = findValidDefaultNamespace(pFileChunk);
  1594. cleanup:
  1595.     return rc;
  1596. }
  1597. HX_RESULT
  1598. CSmil1Renderer::setUpNextGenSmilRenderer()
  1599. {
  1600.     HX_RESULT rc = HXR_OK;
  1601.     rc = CSmilRenderer::HXCreateInstance((IUnknown**)(&m_pNextGenSmilRenderer));
  1602.     if (HXR_OK == rc  &&  m_pNextGenSmilRenderer)
  1603.     {
  1604. IHXSmilToSmilRendererCommunicator* pSmilToSmilComm = NULL;
  1605. if (HXR_OK == m_pNextGenSmilRenderer->
  1606. QueryInterface(IID_IHXSmilToSmilRendererCommunicator,
  1607. (void**) &pSmilToSmilComm))
  1608. {
  1609.     if (HXR_OK ==
  1610.     pSmilToSmilComm->InitSmilStreamProxiedByOtherRenderer(
  1611.     m_pDefaultNamespace))
  1612.     {
  1613. rc = m_pNextGenSmilRenderer->InitPlugin(m_pContext);
  1614.     }
  1615.     HX_RELEASE(pSmilToSmilComm);
  1616. }
  1617. if (HXR_OK == rc)
  1618. {
  1619.     // /XXXEH- note that the REF parameters in GetPluginInfo() and
  1620.     // GetRendererInfo are set by the callee, but we can't do
  1621.     // anything with the values passed back as we've already set these
  1622.     // to our own vals and there's no way to re-set them in the core:
  1623.     BOOL bLoadMultiple = FALSE;
  1624.     const char* pszDescription = NULL;
  1625.     const char* pszCopyright = NULL;
  1626.     const char* pszMoreInfoURL = NULL;
  1627.     ULONG32 ulVersionNumber = 0;
  1628.     rc = m_pNextGenSmilRenderer->GetPluginInfo(bLoadMultiple,
  1629.     pszDescription, pszCopyright, pszMoreInfoURL,
  1630.     ulVersionNumber);
  1631.     if (HXR_OK == rc)
  1632.     {
  1633. const char** ppStreamMimeTypes = NULL;
  1634. ULONG32 ulInitialGranularity = m_ulGranularity;
  1635. rc = m_pNextGenSmilRenderer->GetRendererInfo(
  1636. ppStreamMimeTypes, ulInitialGranularity);
  1637.     }
  1638.     if (HXR_OK == rc)
  1639.     {
  1640. HX_ASSERT(m_bCSmil1StartStreamHasBeenCalled);
  1641. rc = m_pNextGenSmilRenderer->StartStream(m_pStream,
  1642. m_pPlayer);
  1643.     }
  1644.     if (HXR_OK == rc  &&  m_bCSmil1EndStreamHasBeenCalled)
  1645.     {
  1646. rc = m_pNextGenSmilRenderer->EndStream();
  1647.     }
  1648.     if (HXR_OK == rc)
  1649.     {
  1650. if (!m_pHeader)
  1651. {
  1652.     HX_ASSERT(m_pHeader);
  1653.     rc = HXR_UNEXPECTED;
  1654. }
  1655. else
  1656. {
  1657.     rc = m_pNextGenSmilRenderer->OnHeader(m_pHeader);
  1658. }
  1659.     }
  1660.     if (HXR_OK == rc  &&  m_bCSmil1GetDisplayTypeHasBeenCalled)
  1661.     {
  1662. HX_DISPLAY_TYPE ulFlags = HX_DISPLAY_NONE;
  1663. IHXBuffer* pBuffer = NULL;
  1664. rc = m_pNextGenSmilRenderer->GetDisplayType(ulFlags, pBuffer);
  1665. if (pBuffer)
  1666. {
  1667.     // /XXXEH- We can't use it here, so just clean it up:
  1668.     HX_DELETE(pBuffer);
  1669. }
  1670.     }
  1671.     if (HXR_OK == rc  &&  m_bCSmil1InitializeStatisticsHasBeenCalled)
  1672.     {
  1673. rc = m_pNextGenSmilRenderer->InitializeStatistics(m_ulRegistryID);
  1674.     }
  1675. #if defined(DO_INIT_PERSISTENT_ON_NEXTGEN_SMILREND)
  1676.     if (HXR_OK == rc  &&  m_bCSmil1InitPersistenHasBeenCalled)
  1677.     {
  1678. // /NOTE: it's perfectly OK for m_pPersistentParent to be NULL
  1679. rc = m_pNextGenSmilRenderer->InitPersistent(
  1680. m_ulPersistentComponentID, m_uPersistentGroupID,
  1681. m_uPersistentTrackID, m_pPersistentParent);
  1682.     }
  1683. #endif
  1684.     if (HXR_OK == rc  &&  m_bCSmil1GetElementPropertiesHasBeenCalled)
  1685.     {
  1686. IHXValues* pProperties = NULL;
  1687. // /XXXEH- TODO: we need to notify the original caller of this
  1688. // of the next-gen renderer's setting of pProperties.
  1689. rc = m_pNextGenSmilRenderer->GetElementProperties(
  1690. m_uGroupID, m_uTrackID, pProperties);
  1691.     }
  1692.     if (HXR_OK == rc  &&  m_bCSmil1RemoveLayoutSiteGroupHasBeenCalled)
  1693.     {
  1694. // /XXXEH- Need to handle this (unexpected) case by saving the 
  1695. // removed layout site group (which could differ from the
  1696. // add site layout group,  m_pLayoutSiteGroup (or not?):
  1697. HX_ASSERT(!m_bCSmil1RemoveLayoutSiteGroupHasBeenCalled);
  1698.     }
  1699. }
  1700.     }
  1701.     return rc;
  1702. }
  1703. #endif /* defined(HELIX_FEATURE_SMIL2). */