sm1rendr.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:51k
源码类别:

Symbian

开发平台:

C/C++

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