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

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. // system
  39. #include <time.h>
  40. // include
  41. #include "hxtypes.h"
  42. #include "hxwintyp.h"
  43. #include "smiltype.h"
  44. #include "hxcom.h"
  45. #include "hxcomm.h"
  46. #include "ihxpckts.h"
  47. #include "hxcore.h"
  48. #include "hxrendr.h"
  49. #include "hxplugn.h"
  50. #include "hxwin.h"
  51. #include "hxgroup.h"
  52. #include "hxsite2.h"
  53. #include "hxupgrd.h"
  54. #include "hxmon.h"
  55. #include "hxver.h"
  56. #include "hxvport.h"
  57. #include "hxclsnk.h"
  58. #include "hxprefs.h"
  59. #include "hxmmrkr.h" // smldoc.h   dependency
  60. #include "hxinter.h" // smldoc.h   dependency
  61. #include "hxsm2sm.h"
  62. #include "hxerror.h"
  63. // cont
  64. #include "hxstring.h"
  65. #include "chxpckts.h"
  66. #include "smlpkt.h"
  67. // misc
  68. #include "hxurl.h"
  69. #include "hxstrutl.h" /* for SafeS---() */
  70. #include "smlelem.h"
  71. #include "smlutil.h"
  72. // smlrendr
  73. #include "evnthook.h"
  74. #include "siteuser.h"
  75. #include "passivsw.h"
  76. #include "layout.h"
  77. #include "smldoc.h"
  78. #include "smlerror.h"
  79. #include "smlrmlog.h"
  80. #include "smlrendr.h"
  81. #include "smlrendr.ver"
  82. // debug
  83. #include "debugout.h"
  84. #include "hxheap.h"
  85. #ifdef _DEBUG
  86. #undef HX_THIS_FILE
  87. static const char HX_THIS_FILE[] = __FILE__;
  88. #endif
  89. /* We should really define it in a common header file */
  90. #if defined (_WINDOWS ) || defined (WIN32)
  91. #define OS_SEPARATOR_CHAR '\'
  92. #define OS_SEPARATOR_STRING "\"
  93. #elif defined (_UNIX)
  94. #define OS_SEPARATOR_CHAR '/'
  95. #define OS_SEPARATOR_STRING "/"
  96. #elif defined (_MACINTOSH)
  97. #define OS_SEPARATOR_CHAR ':'
  98. #define OS_SEPARATOR_STRING ":"
  99. #endif // defined (_WINDOWS ) || defined (WIN32)
  100. #ifdef _WINDOWS
  101. extern HINSTANCE g_hInstance;
  102. #endif
  103. static const UINT32 INITIAL_GRANULARITY = 67; // XXXMEH - increased interval to help animation CPU
  104. #define SMIL20_AND_UP_STREAM_MIME_TYPE "application/smil"
  105. const char* const CSmilRenderer::zm_pName       = "SMIL";
  106. const char* const CSmilRenderer::zm_pDescription    = "RealNetworks RMA Driver Renderer Plugin";
  107. const char* const CSmilRenderer::zm_pCopyright      = HXVER_COPYRIGHT;
  108. const char* const CSmilRenderer::zm_pMoreInfoURL    = HXVER_MOREINFO;
  109. const char* const CSmilRenderer::zm_pStreamMimeTypes[] =
  110. {
  111. #if defined(HANDLE_BETA1_SMIL_1_0_STREAM)
  112.     "application/rma-driver",
  113. #endif
  114. #if defined(HANDLE_SMIL_1_0_STREAM)
  115.     "application/vnd.rn-rmadriver",
  116. #endif
  117. #if defined(HANDLE_SMIL_2_0_LASTCALL_STREAM)
  118.     SMIL20_AND_UP_STREAM_MIME_TYPE,
  119. #endif
  120. #if defined(HANDLE_SMIL_2_0_CANDIDATE_REC_STREAM)
  121.     SMIL20_AND_UP_STREAM_MIME_TYPE,
  122. #endif
  123. #if defined(HANDLE_SMIL_2_0_STREAM)
  124.     SMIL20_AND_UP_STREAM_MIME_TYPE,
  125. #endif
  126.     NULL
  127. };
  128. const char* const CSmilRenderer::zm_pRecognizedDefaultNamespaces[
  129. NUM_RECOGNIZED_DEFAULT_NAMESPACES+1] =
  130. {
  131.     // /This is the namespace in the <smil...> tag that declares that
  132.     // this is a SMIL 1.0 document that we should handle *correctly* (per
  133.     // spec); the SMIL file format plug-in would have sent any "old"
  134.     // SMIL 1.0 document to the old SMIL 1.0 renderer via the old stream
  135.     // mime type; this is the case for all files that do not contain
  136.     // a default namespace (which is xmlns= as opposed to xmlns:):
  137.     "http://www.w3.org/TR/REC-smil",
  138.     // /This is the SMIL 2.0 Last Call namespace:
  139.     "http://www.w3.org/TR/REC-smil/2000/SMIL20/LC/",
  140.     // /This is the SMIL 2.0 Language Profile Candidate Rec namespace:
  141.     "http://www.w3.org/2000/SMIL20/CR/Language",
  142.     // /This is the SMIL 2.0 Language Profile Proposed Rec namespace
  143.     // created June 2001:  (Fixes PR 55749):
  144.     "http://www.w3.org/2001/SMIL20/PR/Language",
  145.     // /This is the SMIL 2.0 Rec namespace (it became a W3C Rec on 8/7/2001):
  146. #if defined(HANDLE_SMIL_2_0_STREAM)
  147.     // /Adding "/Language" to this string fixes PR 62208:
  148.     "http://www.w3.org/2001/SMIL20/Language",
  149. #endif
  150.     NULL
  151. };
  152. /************************************************************************
  153.  *  Method:
  154.  *    IHXPlugin::InitPlugin
  155.  *  Purpose:
  156.  *    Initializes the plugin for use. This interface must always be
  157.  *    called before any other method is called. This is primarily needed 
  158.  *    so that the plugin can have access to the context for creation of
  159.  *    IHXBuffers and IMalloc.
  160.  */
  161. STDMETHODIMP CSmilRenderer::InitPlugin(IUnknown* /*IN*/ pContext)
  162. {
  163.     m_pContext = pContext;
  164.     m_pContext->AddRef();
  165.     m_pContext->QueryInterface(IID_IHXCommonClassFactory,
  166.     (void**)&m_pCommonClassFactory);
  167.     HX_RELEASE(m_pErrorMessages);
  168.     m_pContext->QueryInterface(IID_IHXErrorMessages,
  169.                                (void**) &m_pErrorMessages);
  170.     return HXR_OK;
  171. }
  172. /************************************************************************
  173.  *  Method:
  174.  *    IHXPlugin::GetPluginInfo
  175.  *  Purpose:
  176.  *    Returns the basic information about this plugin. Including:
  177.  *
  178.  *    bLoadMultiple whether or not this plugin DLL can be loaded
  179.  * multiple times. All File Formats must set
  180.  * this value to TRUE.
  181.  *    pDescription which is used in about UIs (can be NULL)
  182.  *    pCopyright which is used in about UIs (can be NULL)
  183.  *    pMoreInfoURL which is used in about UIs (can be NULL)
  184.  */
  185. STDMETHODIMP CSmilRenderer::GetPluginInfo
  186. (
  187.     REF(BOOL)        /*OUT*/ bLoadMultiple,
  188.     REF(const char*) /*OUT*/ pDescription,
  189.     REF(const char*) /*OUT*/ pCopyright,
  190.     REF(const char*) /*OUT*/ pMoreInfoURL,
  191.     REF(ULONG32)     /*OUT*/ ulVersionNumber
  192. )
  193. {
  194.     bLoadMultiple = TRUE;   // Must be true for file formats.
  195.     pDescription    = (const char*) zm_pDescription;
  196.     pCopyright     = (const char*) zm_pCopyright;
  197.     pMoreInfoURL    = (const char*) zm_pMoreInfoURL;
  198.     ulVersionNumber = TARVER_ULONG32_VERSION;
  199.     return HXR_OK;
  200. }
  201. /************************************************************************
  202.  *  Method:
  203.  *    IHXPlugin::GetRendererInfo
  204.  *  Purpose:
  205.  *    If this object is a file format object this method returns
  206.  *    information vital to the instantiation of file format plugins.
  207.  *    If this object is not a file format object, it should return
  208.  *    HXR_UNEXPECTED.
  209.  */
  210. STDMETHODIMP CSmilRenderer::GetRendererInfo
  211. (
  212.     REF(const char**) /*OUT*/ pStreamMimeTypes,
  213.     REF(UINT32)      /*OUT*/ unInitialGranularity
  214. )
  215. {
  216.     pStreamMimeTypes = (const char**) zm_pStreamMimeTypes;
  217.     unInitialGranularity = m_ulGranularity;
  218.     return HXR_OK;
  219. }
  220. CSmilRenderer::CSmilRenderer()
  221. : m_lRefCount(0)
  222. , m_pContext(NULL)
  223. , m_pStream(NULL)
  224. , m_pPlayer(NULL)
  225. , m_pHeader(NULL)
  226. , m_ulLastTime(0)
  227. , m_pCommonClassFactory(0)
  228. , m_pPacketParser(0)
  229. , m_pSmilDocRenderer(0)
  230. , m_pEngine(0)
  231.         , m_pErrorMessages(NULL)
  232. , m_pClientContext(0)
  233. , m_uLayoutRule(0)
  234. , m_uSourceRule(0)
  235. , m_ulTotalSMILPackets(0)
  236. , m_ulGranularity(INITIAL_GRANULARITY)
  237. , m_pURLFragment(0)
  238. , m_lastOnPacketResult(HXR_OK)
  239. , m_bInMetadata(FALSE)
  240. , m_bUseNestedMeta(TRUE)
  241. , m_pPersistentComponentManager(NULL)    
  242. , m_ulPersistentVersion(0)
  243. , m_persistentType(PersistentSMIL)
  244. , m_bStreamProxiedByOtherRenderer(FALSE)
  245. , m_pVersionNamespaceFromProxyRenderer(NULL)
  246. {
  247.     m_ulPersistentVersion = HX_ENCODE_PROD_VERSION(2, 0, 0, 0);
  248. };
  249. CSmilRenderer::~CSmilRenderer()
  250. {
  251.     if(m_pSmilDocRenderer)
  252.     {
  253. m_pSmilDocRenderer->close(this);
  254. HX_RELEASE(m_pSmilDocRenderer);
  255.     }
  256.     // /First, see if this player has children who need to be cleaned up:
  257.     if (m_pPlayer)
  258.     {
  259. IHXPlayerNavigator* pPlayerNavRoot = NULL;
  260. HX_RESULT pnrslt = m_pPlayer->QueryInterface(IID_IHXPlayerNavigator,
  261. (void**)&pPlayerNavRoot);
  262. if (HXR_OK == pnrslt)
  263. {
  264.     UINT16 uiNumChildren = pPlayerNavRoot->GetNumChildPlayer();
  265.     while (uiNumChildren > 0)
  266.     {
  267. IHXPlayer* pChildPlayer = NULL;
  268. // /GetChildPlayer addrefs pChildPlayer:
  269. pPlayerNavRoot->GetChildPlayer(uiNumChildren-1,pChildPlayer);
  270. HX_ASSERT(NULL != pChildPlayer);
  271. if (pChildPlayer)
  272. {
  273.     IHXPlayerNavigator* pPlayerNavChild = NULL;
  274.     // /RemoveChildPlayer decrefs it:
  275.     pPlayerNavRoot->RemoveChildPlayer(pChildPlayer);
  276.     IHXPlayer* pParentPlayer = NULL;
  277.     pnrslt= pChildPlayer->QueryInterface(
  278.     IID_IHXPlayerNavigator,
  279.     (void**)&pPlayerNavChild);
  280.     if (HXR_OK == pnrslt)
  281.     {
  282. // /GetParentPlayer addrefs pParentPlayer...
  283. pPlayerNavChild->GetParentPlayer(pParentPlayer);
  284. if (pParentPlayer)
  285. {
  286.     // /RemoveParentPlayer decrefs it...
  287.     pPlayerNavChild->RemoveParentPlayer(
  288.     pParentPlayer);
  289.     // /And we need one more to kill our use of it:
  290.     HX_RELEASE(pParentPlayer);
  291. }
  292. // /Now, remove it from client engine's list:
  293. if (m_pEngine)
  294. {
  295.     pnrslt= m_pEngine->ClosePlayer(pChildPlayer);
  296. }
  297. // /And we need one more to kill our use of it:
  298. HX_RELEASE(pChildPlayer);
  299.     }
  300.     HX_RELEASE(pPlayerNavChild);
  301. }
  302. uiNumChildren--;
  303.     }
  304.     HX_RELEASE(pPlayerNavRoot);
  305. }
  306.     }
  307.     HX_RELEASE(m_pContext);
  308.     HX_RELEASE(m_pClientContext);
  309.     HX_RELEASE(m_pStream);
  310.     HX_RELEASE(m_pEngine);
  311.     HX_RELEASE(m_pErrorMessages);
  312.     HX_RELEASE(m_pCommonClassFactory);
  313.     HX_RELEASE(m_pPersistentComponentManager);
  314.     HX_RELEASE(m_pVersionNamespaceFromProxyRenderer);
  315.     HX_DELETE(m_pPacketParser);
  316.     HX_RELEASE(m_pPlayer);
  317.     HX_VECTOR_DELETE(m_pURLFragment);
  318. }
  319. // *** IUnknown methods ***
  320. /////////////////////////////////////////////////////////////////////////
  321. //  Method:
  322. // IUnknown::QueryInterface
  323. //  Purpose:
  324. // Implement this to export the interfaces supported by your 
  325. // object.
  326. //
  327. STDMETHODIMP CSmilRenderer::QueryInterface(REFIID riid, void** ppvObj)
  328. {
  329.     if (IsEqualIID(riid, IID_IUnknown))
  330.     {
  331. AddRef();
  332. *ppvObj = this;
  333. return HXR_OK;
  334.     }
  335.     else if (IsEqualIID(riid, IID_IHXPlugin))
  336.     {
  337. AddRef();
  338. *ppvObj = (IHXPlugin*)this;
  339. return HXR_OK;
  340.     }
  341.     else if (IsEqualIID(riid, IID_IHXRenderer))
  342.     {
  343. AddRef();
  344. *ppvObj = (IHXRenderer*)this;
  345. return HXR_OK;
  346.     }
  347.     else if (IsEqualIID(riid, IID_IHXSiteUser))
  348.     {
  349. HX_ASSERT(0  &&  "Huh?!  CSmilRenderer doesn't implement IHXSiteUser");
  350. AddRef();
  351. *ppvObj = (IHXSiteUser*)this;
  352. return HXR_OK;
  353.     }
  354. /*
  355.     else if (IsEqualIID(riid, IID_IHXValues))
  356.     {
  357. AddRef();
  358. *ppvObj = (IHXValues*)this;
  359. return HXR_OK;
  360.     }
  361. */
  362.     else if (IsEqualIID(riid, IID_IHXStatistics))
  363.     {
  364. AddRef();
  365. *ppvObj = (IHXStatistics*)this;
  366. return HXR_OK;
  367.     }
  368.     else if (IsEqualIID(riid, IID_IHXPersistentRenderer))
  369.     {
  370. AddRef();
  371. *ppvObj = (IHXPersistentRenderer*)this;
  372. return HXR_OK;
  373.     }
  374.     else if (IsEqualIID(riid, IID_IHXSmilToSmilRendererCommunicator))
  375.     {
  376. AddRef();
  377. *ppvObj = (IHXSmilToSmilRendererCommunicator*)this;
  378. return HXR_OK;
  379.     }
  380.     else if (m_pSmilDocRenderer &&
  381.      HXR_OK == m_pSmilDocRenderer->QueryInterface(riid, ppvObj))
  382.     {
  383. return HXR_OK;
  384.     }
  385.     *ppvObj = NULL;
  386.     return HXR_NOINTERFACE;
  387. }
  388. /////////////////////////////////////////////////////////////////////////
  389. //  Method:
  390. // IUnknown::AddRef
  391. //  Purpose:
  392. // Everyone usually implements this the same... feel free to use
  393. // this implementation.
  394. //
  395. STDMETHODIMP_(ULONG32) CSmilRenderer::AddRef()
  396. {
  397.     return InterlockedIncrement(&m_lRefCount);
  398. }
  399. /////////////////////////////////////////////////////////////////////////
  400. //  Method:
  401. // IUnknown::Release
  402. //  Purpose:
  403. // Everyone usually implements this the same... feel free to use
  404. // this implementation.
  405. //
  406. STDMETHODIMP_(ULONG32) CSmilRenderer::Release()
  407. {
  408.     if (InterlockedDecrement(&m_lRefCount) > 0)
  409.     {
  410.         return m_lRefCount;
  411.     }
  412.     delete this;
  413.     return 0;
  414. }
  415. // *** IHXRenderer methods ***
  416. /////////////////////////////////////////////////////////////////////////
  417. //  Method:
  418. // IHXRenderer::StartStream
  419. //  Purpose:
  420. // Called by client engine to inform the renderer of the stream it
  421. // will be rendering. The stream interface can provide access to
  422. // its source or player. This method also provides access to the 
  423. // primary client controller interface.
  424. //
  425. STDMETHODIMP CSmilRenderer::StartStream
  426. (
  427.     IHXStream*     pStream,
  428.     IHXPlayer*     pPlayer
  429. )
  430. {
  431.     MLOG_FLOW(m_pErrorMessages, "CSmilRenderer::StartStream(0x%08x,0x%08x) this=0x%08xn",
  432.               pStream, pPlayer, this);
  433.     HX_RESULT rc = HXR_OK;
  434.     // Save for later use!
  435.     m_pStream  = pStream;
  436.     m_pStream->AddRef();
  437.     m_pPlayer  = pPlayer;
  438.     m_pPlayer->AddRef();
  439.     m_pPlayer->GetClientEngine(m_pEngine);
  440.     m_pPlayer->GetClientContext(m_pClientContext);
  441.     IHXBuffer* pBuffer = NULL;
  442.     IHXRendererAdviseSink* pRendererAdviseSink = NULL;
  443.     IUnknown* pUnknown = NULL;
  444.     m_pPlayer->QueryInterface(IID_IUnknown, (void**) &pUnknown);
  445.     if (pUnknown)
  446.     {
  447.         ::getBooleanPreference(pUnknown, "useNestedMeta", m_bUseNestedMeta);
  448.     }
  449.     HX_RELEASE(pUnknown);
  450.     m_pSmilDocRenderer = new CSmilDocumentRenderer(this, m_pContext);
  451.     m_pSmilDocRenderer->AddRef();
  452.     if (m_bUseNestedMeta  &&
  453.     // /For handling case where SMIL 1.0 renderer is passing this higher-
  454.     // than-1.0-version stream  to this renderer, we don't want to do what
  455.     // the SMIL 1.0 renderer has already set up with the core:
  456.     !m_bStreamProxiedByOtherRenderer)
  457.     {
  458. IHXPersistentComponent* pPersistentComponent = NULL;
  459. if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXPersistentComponentManager, 
  460.        (void**)&m_pPersistentComponentManager))
  461. {
  462.     m_pPersistentComponentManager->CreatePersistentComponent(pPersistentComponent);
  463.     pPersistentComponent->Init((IHXPersistentRenderer*)this);
  464.     pPersistentComponent->AddRendererAdviseSink((IHXRendererAdviseSink*)m_pSmilDocRenderer);
  465.     pPersistentComponent->AddGroupSink((IHXGroupSink*)m_pSmilDocRenderer);
  466.     rc = m_pPersistentComponentManager->AddPersistentComponent(pPersistentComponent);
  467. }
  468.     }
  469.     else if (!m_bStreamProxiedByOtherRenderer)
  470.     {
  471. IHXPersistenceManager* pMgr = 0;
  472. if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXPersistenceManager, 
  473.     (void**)&pMgr))
  474. {
  475.     IUnknown* pUnk = 0;
  476.     if(HXR_OK == pMgr->GetPersistentComponent(pUnk))
  477.     {
  478. rc = HXR_FAIL;
  479. CSmilSMILSyntaxErrorHandler errHandler(m_pContext);
  480. errHandler.ReportError(SMILErrorMetaDatatype, NULL, 0);
  481. pUnk->Release();
  482.     }
  483.     else if(HXR_OK == QueryInterface(IID_IUnknown, (void**)&pUnk))
  484.     {
  485. pMgr->AddPersistentComponent(pUnk);
  486. pUnk->Release();
  487.     }
  488.     pMgr->Release();
  489. }
  490. IHXDriverStreamManager* pDriverStreamMgr = 0;
  491. if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXDriverStreamManager,
  492.     (void**)&pDriverStreamMgr))
  493. {
  494.     if(!m_bStreamProxiedByOtherRenderer  &&
  495.     HXR_OK == m_pSmilDocRenderer->QueryInterface(IID_IHXRendererAdviseSink, 
  496.     (void**)&pRendererAdviseSink))
  497.     {
  498. pDriverStreamMgr->AddRendererAdviseSink(pRendererAdviseSink);
  499. pRendererAdviseSink->Release();
  500.     }
  501.     pDriverStreamMgr->Release();
  502. }
  503. IHXGroupManager* pGrpMgr = 0;
  504. if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXGroupManager,
  505.     (void**)&pGrpMgr))
  506. {
  507.     IHXGroupSink* pSnk = 0;
  508.     if(!m_bStreamProxiedByOtherRenderer  &&
  509.     HXR_OK == m_pSmilDocRenderer->QueryInterface(
  510.     IID_IHXGroupSink, (void**)&pSnk))
  511.     {
  512. pGrpMgr->AddSink(pSnk);
  513. pSnk->Release();
  514.     }
  515. }
  516. HX_RELEASE(pGrpMgr);
  517.     }
  518.     generatePreFix();
  519.     return rc;
  520. }
  521. /////////////////////////////////////////////////////////////////////////
  522. //  Method:
  523. // IHXRenderer::EndStream
  524. //  Purpose:
  525. // Called by client engine to inform the renderer that the stream
  526. // is was rendering is closed.
  527. //
  528. STDMETHODIMP CSmilRenderer::EndStream()
  529. {
  530.     MLOG_FLOW(m_pErrorMessages,
  531.               "CSmilRenderer::EndStream() this=0x%08xn", this);
  532.     if(m_pSmilDocRenderer)
  533.     {
  534. m_pSmilDocRenderer->endStream();
  535.     }
  536.     if(m_pPlayer)
  537.     {
  538. if (m_bUseNestedMeta  &&  !m_bStreamProxiedByOtherRenderer)
  539. {
  540.     IHXPersistentComponent* pPersistentComponent = NULL;
  541.     IHXRendererAdviseSink* pRendererAdviseSink = 0;
  542.     if(m_pPersistentComponentManager && HXR_OK == m_pPersistentComponentManager->GetPersistentComponent( m_pSmilDocRenderer->m_ulPersistentComponentID,
  543.                                                                                  pPersistentComponent))
  544.     {
  545. pPersistentComponent->RemoveRendererAdviseSink((IHXRendererAdviseSink*)m_pSmilDocRenderer);
  546. pPersistentComponent->RemoveGroupSink((IHXGroupSink*)m_pSmilDocRenderer);
  547.     }
  548.     HX_RELEASE(pPersistentComponent);     
  549. }
  550. else if (!m_bStreamProxiedByOtherRenderer)
  551. {
  552.     IHXGroupManager* pGrpMgr = 0;
  553.     if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXGroupManager, 
  554. (void**)&pGrpMgr))
  555.     {
  556. IHXGroupSink* pSnk = 0;
  557. if(m_pSmilDocRenderer &&
  558.     HXR_OK == m_pSmilDocRenderer->QueryInterface(IID_IHXGroupSink, 
  559.     (void**)&pSnk))
  560. {
  561.     pGrpMgr->RemoveSink(pSnk);
  562.     pSnk->Release();
  563. }
  564. pGrpMgr->Release();
  565.     }
  566.     IHXDriverStreamManager* pStrmMgr = 0;
  567.     if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXDriverStreamManager,
  568. (void**)&pStrmMgr))
  569.     {
  570. IHXRendererAdviseSink* pSnk = 0;
  571. if(m_pSmilDocRenderer &&
  572.     HXR_OK == m_pSmilDocRenderer->QueryInterface(
  573.     IID_IHXRendererAdviseSink, (void**)&pSnk))
  574. {
  575.     pStrmMgr->RemoveRendererAdviseSink(pSnk);
  576.     pSnk->Release();
  577. }
  578. pStrmMgr->Release();
  579.     }
  580. }
  581. IHXClientAdviseSink* pSnk = NULL;
  582. if(!m_bStreamProxiedByOtherRenderer  &&
  583. m_pSmilDocRenderer  &&
  584. HXR_OK == m_pSmilDocRenderer->QueryInterface(
  585. IID_IHXClientAdviseSink, (void**)&pSnk))
  586. {
  587.     m_pPlayer->RemoveAdviseSink(pSnk);
  588.     HX_RELEASE(pSnk);
  589. }
  590.     }
  591.     HX_RELEASE(m_pStream);
  592.     // /See if the player has child players who need to be stopped:
  593.     if (m_pPlayer)
  594.     {
  595. IHXPlayerNavigator* pPlayerNavRoot = NULL;
  596. HX_RESULT pnrslt = m_pPlayer->QueryInterface(IID_IHXPlayerNavigator,
  597. (void**)&pPlayerNavRoot);
  598. if (HXR_OK == pnrslt)
  599. {
  600.     UINT16 uiChild = pPlayerNavRoot->GetNumChildPlayer();
  601.     while (uiChild > 0)
  602.     {
  603. IHXPlayer* pChildPlayer = NULL;
  604. // /GetChildPlayer addrefs pChildPlayer:
  605. pPlayerNavRoot->GetChildPlayer(uiChild-1, pChildPlayer);
  606. HX_ASSERT(pChildPlayer);
  607. if (pChildPlayer)
  608. {
  609.     pChildPlayer->Stop();
  610.     HX_RELEASE(pChildPlayer);
  611. }
  612. uiChild--;
  613.     }
  614.     HX_RELEASE(pPlayerNavRoot);
  615. }
  616.     }
  617.     
  618.     return HXR_OK;
  619. }
  620. /////////////////////////////////////////////////////////////////////////
  621. //  Method:
  622. // IHXRenderer::OnHeader
  623. //  Purpose:
  624. // Called by client engine when a header for this renderer is 
  625. // available. The header will arrive before any packets.
  626. //
  627. STDMETHODIMP CSmilRenderer::OnHeader(IHXValues* pHeader)
  628. {
  629.     MLOG_FLOW(m_pErrorMessages,
  630.               "CSmilRenderer::OnHeader(0x%08x) this=0x%08xn", pHeader, this);
  631.     // check stream and content versions so an upgrade can
  632.     // be called if necessary...
  633.     BOOL bVersionOK = TRUE;
  634.     UINT32 ulStreamVersion = 0;
  635.     UINT32 ulContentVersion = 0;
  636.     
  637.     if (HXR_OK == pHeader->GetPropertyULONG32("StreamVersion", ulStreamVersion))
  638.     {
  639. UINT32 ulMajorVersion = HX_GET_MAJOR_VERSION(ulStreamVersion);
  640. UINT32 ulMinorVersion = HX_GET_MINOR_VERSION(ulStreamVersion);
  641. if((ulMajorVersion > STREAM_MAJOR_VERSION) ||
  642.    (ulMinorVersion > STREAM_MINOR_VERSION &&
  643.     ulMajorVersion == STREAM_MAJOR_VERSION))
  644. {
  645.     bVersionOK = FALSE;
  646. }
  647.     }
  648.     if(bVersionOK &&
  649.        HXR_OK == pHeader->GetPropertyULONG32("ContentVersion", ulContentVersion))
  650.     {
  651. UINT32 ulMajorVersion = HX_GET_MAJOR_VERSION(ulContentVersion);
  652. UINT32 ulMinorVersion = HX_GET_MINOR_VERSION(ulContentVersion);
  653. if((ulMajorVersion > CONTENT_MAJOR_VERSION) ||
  654.    (ulMinorVersion > CONTENT_MINOR_VERSION &&
  655.     ulMajorVersion == CONTENT_MAJOR_VERSION))
  656. {
  657.     bVersionOK = FALSE;
  658. }
  659.     }
  660.     if(!bVersionOK)
  661.     {
  662. IHXUpgradeCollection* pUpColl = NULL;
  663. if(m_pPlayer &&
  664.    (HXR_OK == m_pPlayer->QueryInterface(IID_IHXUpgradeCollection,
  665. (void**)&pUpColl)))
  666. {
  667.     CHXBuffer* pBuffer = new CHXBuffer;
  668.     pBuffer->AddRef();
  669.     pBuffer->Set((BYTE*)SMIL20_AND_UP_STREAM_MIME_TYPE, 
  670. strlen(SMIL20_AND_UP_STREAM_MIME_TYPE)+1);
  671.     pUpColl->Add(eUT_Required, pBuffer, 0, 0);
  672.     HX_RELEASE(pBuffer);
  673.     HX_RELEASE(pUpColl);
  674. }
  675. return HXR_FAIL;
  676.     }
  677.     m_pPacketParser = new CSmilPacketParser;
  678.     m_pSmilDocRenderer->onHeader(pHeader);
  679.     if (!m_pSmilDocRenderer->IsNestedMetaSupported())
  680.     {
  681. return HXR_INVALID_METAFILE;
  682.     }
  683.     IHXClientAdviseSink* pSnk = 0;
  684.     if(!m_bStreamProxiedByOtherRenderer  &&
  685.     HXR_OK == m_pSmilDocRenderer->QueryInterface(
  686.     IID_IHXClientAdviseSink, (void**)&pSnk))
  687.     {
  688. m_pPlayer->AddAdviseSink(pSnk);
  689. HX_RELEASE(pSnk);
  690.     }
  691.     if (!m_bUseNestedMeta)
  692.     {
  693. /* SMIL renderer currently removes previously added
  694.  * groups, if any. This is to solve the case where we have 
  695.  * SMIL file within a RAM file. We will do something more
  696.  * sensible later.
  697.  */
  698. IHXGroupManager* pGrpMgr = 0;
  699. if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXGroupManager,
  700.     (void**)&pGrpMgr))
  701. {
  702.     while(pGrpMgr && pGrpMgr->GetGroupCount() > 0)
  703.     {
  704. pGrpMgr->RemoveGroup(0);
  705.     }
  706. }
  707. HX_RELEASE(pGrpMgr);
  708.     }
  709.     return HXR_OK;
  710. }
  711. /////////////////////////////////////////////////////////////////////////
  712. //  Method:
  713. // IHXRenderer::OnPacket
  714. //  Purpose:
  715. // Called by client engine when a packet for this renderer is 
  716. // due.
  717. //
  718. STDMETHODIMP CSmilRenderer::OnPacket(IHXPacket* pPacket, 
  719.  LONG32 lTimeOffset)
  720. {
  721.     MLOG_FLOW(m_pErrorMessages,
  722.               "CSmilRenderer::OnPacket(0x%08x,%ld) this=0x%08xn",
  723.               pPacket, lTimeOffset, this);
  724.     HX_RESULT rc = HXR_OK;
  725.     HX_ASSERT(lTimeOffset <= 0);
  726.     //Fix for PR 23352: if we already returned a fail value from
  727.     // a prior OnPacket(), don't process this OnPacket():
  728.     if (HXR_OK != m_lastOnPacketResult)
  729.     {
  730. return m_lastOnPacketResult;
  731.     }
  732.     IHXBuffer* pBuffer = pPacket->GetBuffer();
  733.     if(pBuffer)
  734.     {
  735. // /If parse() runs into a missing-quote situation,
  736. // we should stop and display an error.  Note that
  737. // CSmilPacketParser::parse(..)  does not keep track of
  738. // line numbers; TODO: add line-number counting to it.
  739. CSmilPacketParser::SMILPacketParseResult pktPrsRslt
  740. = CSmilPacketParser::SMILUnknown;
  741. CSmilPacket* pSmilPacket = m_pPacketParser->parse(
  742.     pBuffer, pktPrsRslt);
  743. if (CSmilPacketParser::SMILMissingQuote
  744. == pktPrsRslt)
  745. {
  746.     CSmilSMILSyntaxErrorHandler errHandler(m_pContext);
  747.     errHandler.ReportError(SMILErrorBadAttribute,
  748.     "missing quote", 0);
  749. }
  750. else if(pSmilPacket)
  751. {
  752.     switch(pSmilPacket->m_type)
  753.     {
  754. case CSmilPacket::SMILDocument:
  755. {
  756.     rc = handleSMILDocumentPacket(
  757. (CSmilDocumentPacket*)pSmilPacket);
  758.     if (HXR_OK != rc)
  759.     {
  760. m_lastOnPacketResult = rc;
  761.     }
  762. }
  763. break;
  764. default:
  765. break;
  766.     }
  767.     delete pSmilPacket;
  768. }
  769. HX_RELEASE(pBuffer);
  770.     }
  771.     return rc;
  772. }
  773. /////////////////////////////////////////////////////////////////////////
  774. //  Method:
  775. // IHXRenderer::OnTimeSync
  776. //  Purpose:
  777. // Called by client engine to inform the renderer of the current
  778. // time relative to the streams synchronized time-line. The 
  779. // renderer should use this time value to update its display or
  780. // render it's stream data accordingly.
  781. //
  782. STDMETHODIMP CSmilRenderer::OnTimeSync(ULONG32 ulTime)
  783. {
  784.     MLOG_FLOW(m_pErrorMessages,
  785.               "CSmilRenderer::OnTimeSync(%lu) this=0x%08xn", ulTime, this);
  786.     HX_RESULT rc = HXR_OK;
  787.     if(m_pSmilDocRenderer)
  788.     {
  789. rc = m_pSmilDocRenderer->onTimeSync(ulTime);
  790.     }
  791.     if (rc != HXR_OUTOFMEMORY)
  792.     {
  793.         rc = HXR_OK;
  794.     }
  795.     return rc;
  796. }
  797. /////////////////////////////////////////////////////////////////////////
  798. //  Method:
  799. // IHXRenderer::OnPreSeek
  800. //  Purpose:
  801. // Called by client engine to inform the renderer that a seek is
  802. // about to occur. The render is informed the last time for the 
  803. // stream's time line before the seek, as well as the first new
  804. // time for the stream's time line after the seek will be completed.
  805. //
  806. STDMETHODIMP CSmilRenderer::OnPreSeek(ULONG32 ulOldTime, ULONG32 ulNewTime)
  807. {
  808.     MLOG_FLOW(m_pErrorMessages,
  809.               "CSmilRenderer::OnPreSeek(%lu,%lu) this=0x%08xn",
  810.               ulOldTime, ulNewTime, this);
  811.     HX_RESULT rc = HXR_OK;
  812.     if(m_pSmilDocRenderer)
  813.     {
  814. rc = m_pSmilDocRenderer->onPreSeek(ulOldTime, ulNewTime);
  815.     }
  816.     return rc;
  817. }
  818. /////////////////////////////////////////////////////////////////////////
  819. //  Method:
  820. // IHXRenderer::OnPostSeek
  821. //  Purpose:
  822. // Called by client engine to inform the renderer that a seek has
  823. // just occured. The render is informed the last time for the 
  824. // stream's time line before the seek, as well as the first new
  825. // time for the stream's time line after the seek.
  826. //
  827. STDMETHODIMP CSmilRenderer::OnPostSeek(ULONG32 ulOldTime,
  828.    ULONG32 ulNewTime)
  829. {
  830.     MLOG_FLOW(m_pErrorMessages,
  831.               "CSmilRenderer::OnPostSeek(%lu,%lu) this=0x%08xn",
  832.               ulOldTime, ulNewTime, this);
  833.     return HXR_OK;
  834. }
  835. /////////////////////////////////////////////////////////////////////////
  836. //  Method:
  837. // IHXRenderer::OnPause
  838. //  Purpose:
  839. // Called by client engine to inform the renderer that a pause has
  840. // just occured. The render is informed the last time for the 
  841. // stream's time line before the pause.
  842. //
  843. STDMETHODIMP CSmilRenderer::OnPause(ULONG32 ulTime)
  844. {
  845.     MLOG_FLOW(m_pErrorMessages,
  846.               "CSmilRenderer::OnPause(%lu) this=0x%08xn", ulTime, this);
  847.     if( m_pSmilDocRenderer )
  848.     {
  849.         m_pSmilDocRenderer->unlockSiteComposition();
  850.     }
  851.     
  852.     return HXR_OK;
  853. }
  854. /////////////////////////////////////////////////////////////////////////
  855. //  Method:
  856. // IHXRenderer::OnBegin
  857. //  Purpose:
  858. // Called by client engine to inform the renderer that a begin or
  859. // resume has just occured. The render is informed the first time 
  860. // for the stream's time line after the resume.
  861. //
  862. STDMETHODIMP CSmilRenderer::OnBegin(ULONG32 ulTime)
  863. {
  864.     MLOG_FLOW(m_pErrorMessages,
  865.               "CSmilRenderer::OnBegin(%lu) this=0x%08xn", ulTime, this);
  866.     if( m_pSmilDocRenderer )
  867.     {
  868.         m_pSmilDocRenderer->lockSiteComposition();
  869.     }
  870.     return HXR_OK;
  871. }
  872. /////////////////////////////////////////////////////////////////////////
  873. //  Method:
  874. // IHXRenderer::OnBuffering
  875. //  Purpose:
  876. // Called by client engine to inform the renderer that buffering
  877. // of data is occuring. The render is informed of the reason for
  878. // the buffering (start-up of stream, seek has occured, network
  879. // congestion, etc.), as well as percentage complete of the 
  880. // buffering process.
  881. //
  882. STDMETHODIMP CSmilRenderer::OnBuffering(ULONG32 ulFlags,
  883. UINT16 unPercentComplete)
  884. {
  885.     MLOG_FLOW(m_pErrorMessages,
  886.               "CSmilRenderer::OnBuffering(%lu,%u) this=0x%08xn",
  887.               ulFlags, unPercentComplete, this);
  888.     return HXR_OK;
  889. }
  890. /////////////////////////////////////////////////////////////////////////
  891. //  Method:
  892. // IHXRenderer::GetDisplayType
  893. //  Purpose:
  894. // Called by client engine to ask the renderer for it's preferred
  895. // display type. When layout information is not present, the 
  896. // renderer will be asked for it's prefered display type. Depending
  897. // on the display type a buffer of additional information may be 
  898. // needed. This buffer could contain information about preferred
  899. // window size.
  900. //
  901. STDMETHODIMP CSmilRenderer::GetDisplayType
  902. (
  903.     REF(HX_DISPLAY_TYPE)   ulFlags,
  904.     REF(IHXBuffer*)     pBuffer
  905. )
  906. {
  907.     ulFlags = HX_DISPLAY_NONE;
  908.     return HXR_OK;
  909. }
  910. /************************************************************************
  911.  * Method:
  912.  *     IHXRenderer::OnEndofPackets
  913.  * Purpose:
  914.  *     Called by client engine to inform the renderer that all the
  915.  *     packets have been delivered. However, if the user seeks before
  916.  *     EndStream() is called, renderer may start getting packets again
  917.  *     and the client engine will eventually call this function again.
  918.  */
  919. STDMETHODIMP CSmilRenderer::OnEndofPackets(void)
  920. {
  921.     MLOG_FLOW(m_pErrorMessages,
  922.               "CSmilRenderer::OnEndofPackets() this=0x%08xn", this);
  923.     return HXR_OK;
  924. }
  925. /************************************************************************
  926.  * Method:
  927.  *     IHXStatistics::Init
  928.  * Purpose:
  929.  *     Pass registry ID to the caller
  930.  *
  931.  */
  932. STDMETHODIMP
  933. CSmilRenderer::InitializeStatistics
  934. (
  935.     UINT32 /*IN*/ ulRegistryID
  936. )
  937. {
  938.     IHXRegistry* pRegistry = NULL;
  939.     if (m_pContext &&
  940. HXR_OK == m_pContext->QueryInterface(IID_IHXRegistry, (void**)&pRegistry))
  941.     {
  942. char     szRegistryEntry[MAX_DISPLAY_NAME] = {0}; /* Flawfinder: ignore */
  943. IHXBuffer*     pszRegistryName = NULL;
  944. // Get the current registry key name
  945. if (HXR_OK == pRegistry->GetPropName(ulRegistryID, pszRegistryName))
  946. {
  947.     IHXBuffer* pValue = new CHXBuffer();
  948.     pValue->AddRef();
  949.     SafeSprintf(szRegistryEntry, MAX_DISPLAY_NAME, "%s.name", pszRegistryName->GetBuffer());
  950.     pValue->Set((const UCHAR*)zm_pName, strlen(zm_pName) + 1);
  951.     pRegistry->AddStr(szRegistryEntry, pValue);
  952.     HX_RELEASE(pValue);
  953.     HX_RELEASE(pszRegistryName);
  954. }
  955. HX_RELEASE(pRegistry);
  956.     }
  957.     return HXR_OK;
  958. }
  959. /************************************************************************
  960.  * Method:
  961.  *     IHXStatistics::Update
  962.  * Purpose:
  963.  *     Notify the client to update its statistics stored in the registry
  964.  *
  965.  */
  966. STDMETHODIMP 
  967. CSmilRenderer::UpdateStatistics()
  968. {
  969.     return HXR_OK;
  970. }
  971. // IHXPersistentRenderer methods
  972. STDMETHODIMP
  973. CSmilRenderer::InitPersistent(UINT32 ulPersistentComponentID,
  974.      UINT16 uPersistentGroupID,
  975.      UINT16 uPersistentTrackID,
  976.      IHXPersistentRenderer* pPersistentParent)
  977. {
  978.     return m_pSmilDocRenderer->InitPersistent(ulPersistentComponentID,
  979.       uPersistentGroupID,
  980.       uPersistentTrackID,
  981.       pPersistentParent);
  982. }
  983. STDMETHODIMP
  984. CSmilRenderer::GetPersistentID(REF(UINT32) ulPersistentComponentID)
  985. {
  986.     ulPersistentComponentID = m_pSmilDocRenderer->m_ulPersistentComponentID;
  987.     return HXR_OK;
  988. }
  989. STDMETHODIMP
  990. CSmilRenderer::GetPersistentProperties(REF(IHXValues*) pProperties)
  991. {
  992.     HX_RESULT rc = HXR_OK;
  993.     pProperties = new CHXHeader();
  994.     pProperties->AddRef();
  995.     pProperties->SetPropertyULONG32("PersistentType", m_persistentType);
  996.     pProperties->SetPropertyULONG32("PersistentVersion", m_ulPersistentVersion);
  997.     return rc;
  998. }
  999. STDMETHODIMP
  1000. CSmilRenderer::GetElementProperties(UINT16 uGroupID,
  1001.     UINT16 uTrackID,
  1002.                                     REF(IHXValues*) pProperties)
  1003. {
  1004.     return m_pSmilDocRenderer->GetElementProperties(uGroupID,
  1005.     uTrackID,
  1006.     pProperties);
  1007. }
  1008. STDMETHODIMP
  1009. CSmilRenderer::AttachElementLayout(UINT16     uGroupID,
  1010.    UINT16     uTrackID,
  1011.    IHXRenderer*    pRenderer,
  1012.    IHXStream*     pStream,
  1013.    IHXValues*     pProps)
  1014. {
  1015.     return m_pSmilDocRenderer->AttachElementLayout(uGroupID,
  1016.    uTrackID,
  1017.    pRenderer,
  1018.    pStream,
  1019.    pProps);
  1020. }
  1021. STDMETHODIMP
  1022. CSmilRenderer::DetachElementLayout(IUnknown* pLSG)
  1023. {
  1024.     return m_pSmilDocRenderer->DetachElementLayout(pLSG);
  1025. }
  1026. /************************************************************************
  1027.  * Method:
  1028.  *     IHXSmilToSmilRendererCommunicator::InitSmilStreamProxiedByOtherRenderer
  1029.  * Purpose:
  1030.  *     Notify the client to update its statistics stored in the registry
  1031.  *
  1032.  */
  1033. // IHXSmilToSmilRendererCommunicator methods
  1034. STDMETHODIMP
  1035. CSmilRenderer::InitSmilStreamProxiedByOtherRenderer(IHXBuffer* pDefaultNamespace)
  1036. {
  1037.     HX_RESULT rc = HXR_FAIL;
  1038.     m_bStreamProxiedByOtherRenderer = TRUE;
  1039.     if (pDefaultNamespace  &&  pDefaultNamespace->GetSize() > 0)
  1040.     {
  1041. HX_RELEASE(m_pVersionNamespaceFromProxyRenderer);
  1042. m_pVersionNamespaceFromProxyRenderer = pDefaultNamespace;
  1043. m_pVersionNamespaceFromProxyRenderer->AddRef();
  1044. rc = HXR_OK;
  1045.     }
  1046.     return rc;
  1047. }
  1048. STDMETHODIMP
  1049. CSmilRenderer::GetElementStatus(UINT16     uGroupID,
  1050. UINT16     uTrackID,
  1051. UINT32     ulCurrentTime,
  1052. REF(IHXValues*)    pStatus)
  1053. {
  1054.     return m_pSmilDocRenderer->GetElementStatus(uGroupID,
  1055. uTrackID,
  1056. ulCurrentTime,
  1057. pStatus);
  1058. }
  1059. HX_RESULT STDAPICALLTYPE CSmilRenderer::HXCreateInstance(IUnknown** ppIUnknown)
  1060. {
  1061.     HX_RESULT retVal = HXR_FAIL;
  1062.     if (ppIUnknown)
  1063.     {
  1064.         CSmilRenderer* pObj = new CSmilRenderer();
  1065.         if (pObj)
  1066.         {
  1067.             retVal = pObj->QueryInterface(IID_IUnknown, (void**) ppIUnknown);
  1068.             if (FAILED(retVal))
  1069.             {
  1070.                 HX_DELETE(pObj);
  1071.             }
  1072.         }
  1073.     }
  1074.     return retVal;
  1075. }
  1076. HX_RESULT STDAPICALLTYPE CSmilRenderer::CanUnload2(void)
  1077. {
  1078.     return ((CHXBaseCountingObject::ObjectsActive() > 0) ? HXR_FAIL : HXR_OK);
  1079. }
  1080. HX_RESULT
  1081. CSmilRenderer::HandleAddLayoutSiteGroup(IUnknown* pLSG)
  1082. {
  1083.     HX_RESULT     rc = HXR_OK;
  1084.     IHXValues*     pProps = NULL;
  1085.     IHXPersistentRenderer* pPersistentParentRenderer = NULL;
  1086.     pPersistentParentRenderer = m_pSmilDocRenderer->m_pPersistentParentRenderer;
  1087.     // nested meta, get layout from its parent
  1088.     if (pPersistentParentRenderer)
  1089.     {
  1090. pProps = new CHXHeader();
  1091. if (pProps)
  1092. {
  1093.     pProps->AddRef();
  1094.     pProps->SetPropertyULONG32("PersistentType", m_persistentType);
  1095. }
  1096. rc = pPersistentParentRenderer->AttachElementLayout(m_pSmilDocRenderer->m_uPersistentGroupID,
  1097.     m_pSmilDocRenderer->m_uPersistentTrackID,
  1098.     (IHXRenderer*)pLSG,
  1099.     NULL,
  1100.     pProps);
  1101.     }
  1102.     else if (m_pPlayer)
  1103.     {
  1104. IHXLayoutSiteGroupManager* pLSGMgr = 0;
  1105. if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXLayoutSiteGroupManager, (void**)&pLSGMgr))
  1106. {
  1107.     rc = pLSGMgr->AddLayoutSiteGroup(pLSG);
  1108.     pLSGMgr->Release();
  1109. }
  1110.     }
  1111.     HX_RELEASE(pProps);
  1112.     return rc;
  1113. }
  1114. HX_RESULT
  1115. CSmilRenderer::HandleRemoveLayoutSiteGroup(IUnknown* pLSG)
  1116. {
  1117.     HX_RESULT     rc = HXR_OK;
  1118.     IHXPersistentRenderer* pPersistentParentRenderer = NULL;
  1119.     pPersistentParentRenderer = m_pSmilDocRenderer->m_pPersistentParentRenderer;
  1120.     // nested meta, remove layout from its parent
  1121.     if (pPersistentParentRenderer)
  1122.     {
  1123. rc = pPersistentParentRenderer->DetachElementLayout(pLSG);
  1124.     }
  1125.     else if (m_pPlayer)
  1126.     {
  1127. IHXLayoutSiteGroupManager* pLSGMgr = 0;
  1128. if(HXR_OK == m_pPlayer->QueryInterface(IID_IHXLayoutSiteGroupManager, (void**)&pLSGMgr))
  1129. {
  1130.     rc = pLSGMgr->RemoveLayoutSiteGroup(pLSG);
  1131.     pLSGMgr->Release();
  1132. }
  1133.     }
  1134.     return rc;
  1135. }
  1136. HX_RESULT
  1137. CSmilRenderer::HandleAttachElementLayout(IUnknown* pLSG, IHXValues* pProps)
  1138. {
  1139.     HX_RESULT rc = HXR_OK;
  1140.     if (m_pPersistentComponentManager)
  1141.     {
  1142. rc = m_pPersistentComponentManager->AttachPersistentComponentLayout(pLSG, pProps);
  1143.     }
  1144.     return rc;
  1145. }
  1146. HX_RESULT
  1147. CSmilRenderer::handleSMILDocumentPacket(CSmilDocumentPacket* pPacket)
  1148. {
  1149.     HX_RESULT rc = HXR_OK;
  1150.     if(pPacket->m_version == RMA_DRIVER_VERSION)
  1151.     {
  1152. CHXBuffer* pBuffer = new CHXBuffer;
  1153. pBuffer->AddRef();
  1154. BOOL bLastPacket = FALSE;
  1155. UINT32 ulDocLen = (UINT32)pPacket->m_document.GetLength();
  1156. HX_ASSERT(ulDocLen);
  1157. // /Extra safety check:
  1158. if (0 == ulDocLen)
  1159. {
  1160.     rc = HXR_UNEXPECTED;
  1161.     bLastPacket = FALSE;
  1162. }
  1163. else
  1164. {
  1165.     pBuffer->Set((const BYTE*)(const char*)pPacket->m_document,
  1166.     pPacket->m_document.GetLength());
  1167.     m_ulTotalSMILPackets++;
  1168.     bLastPacket = pPacket->m_ulTotalPackets == m_ulTotalSMILPackets;
  1169.     rc = m_pSmilDocRenderer->onPacket(pBuffer, bLastPacket);
  1170.     const char* pPktContents = (const char*)pPacket->m_document;
  1171.     while (pPktContents)
  1172.     {
  1173. // /See if there is a <metadata> tag; if so, add it and all
  1174. // the rest of the text up to </metadata> to m_metadata:
  1175. // /XXXEH- TODO: make sure we're not inside a <!--comment-->!:
  1176. // Note, however, that comments are being stripped by the
  1177. // file format, so we need only do this if the ff changes
  1178. // in this respect.
  1179. char* pMetadataTag =
  1180. (char*)strstr(pPktContents, "<metadata");
  1181. char* pMetadataEndTag =
  1182. (char*)strstr(pPktContents, "</metadata");
  1183. char* pVeryEndOfTag = pMetadataEndTag != NULL ?
  1184.     (char*)strchr(pMetadataEndTag, '>') : NULL;
  1185. if (m_bInMetadata)
  1186. {
  1187.     m_bInMetadata = (NULL == pMetadataEndTag);
  1188.     // /Concatinate all the stuff up to the end tag; if there's
  1189.     // no end tag, then concatinate the whole packet:
  1190.     if (NULL != pMetadataEndTag)
  1191.     {
  1192. if (strlen(pVeryEndOfTag) > 1)
  1193. {
  1194.     char savedChar = pVeryEndOfTag[1];
  1195.     pVeryEndOfTag[1] = NULL;
  1196.     m_pSmilDocRenderer->m_metadata += pPktContents;
  1197.     pVeryEndOfTag[1] = savedChar;
  1198. }
  1199.     }
  1200.     else
  1201.     {
  1202. m_pSmilDocRenderer->m_metadata += pPktContents;
  1203.     }
  1204. }
  1205. if (pMetadataTag)
  1206. {
  1207.     HX_ASSERT(!m_bInMetadata);
  1208.     // /In case there is another end tag (multiple metadata tags):
  1209.     if (pMetadataTag > pMetadataEndTag  &&  NULL != pMetadataEndTag)
  1210.     {
  1211. pMetadataEndTag = pVeryEndOfTag != NULL?
  1212. strstr(pVeryEndOfTag, "</metadata") : NULL;
  1213. pVeryEndOfTag = pMetadataEndTag!=NULL?
  1214. strchr(pMetadataEndTag, '>') : NULL;
  1215.     }
  1216.     // /Concatinate all the stuff up to the end tag; if there's
  1217.     // no end tag, then concatinate the whole packet:
  1218.     if (NULL != pMetadataEndTag)
  1219.     {
  1220. char* pVeryEndOfTag = strchr(pMetadataEndTag, '>');
  1221. if (strlen(pVeryEndOfTag) > 1)
  1222. {
  1223.     char savedChar = pVeryEndOfTag[1];
  1224.     pVeryEndOfTag[1] = NULL;
  1225.     m_pSmilDocRenderer->m_metadata += pMetadataTag;
  1226.     pVeryEndOfTag[1] = savedChar;
  1227. }
  1228.     }
  1229.     else
  1230.     {
  1231. m_bInMetadata = TRUE;
  1232. m_pSmilDocRenderer->m_metadata += pMetadataTag;
  1233.     }
  1234. }
  1235. pPktContents = (const char*)pVeryEndOfTag;
  1236.     }
  1237.     // /See if the <smil ...> tag had a default namespace declared
  1238.     // in it; if so, see if we recognize it.  If there is none or
  1239.     // if we don't recognize it, try an auto upgrade:
  1240.     BOOL bDefaultNamespaceRecognized = FALSE;
  1241.     const char* pDefaultNamespace =
  1242.     m_pSmilDocRenderer->getDefaultNamespace();
  1243.     if (pDefaultNamespace  &&  strlen(pDefaultNamespace)>0)
  1244.     {
  1245. UINT32 ui=0;
  1246. for (ui = 0; ui < NUM_RECOGNIZED_DEFAULT_NAMESPACES; ui++)
  1247. {
  1248.     if (0 == strcmp(
  1249.     (const char*) zm_pRecognizedDefaultNamespaces[ui],
  1250.     pDefaultNamespace) )
  1251.     {
  1252. bDefaultNamespaceRecognized = TRUE;
  1253. break;
  1254.     }
  1255. }
  1256.     }
  1257.     else
  1258.     {
  1259. #if defined(HANDLE_BETA1_SMIL_1_0_STREAM)  || defined(HANDLE_SMIL_1_0_STREAM)
  1260. bDefaultNamespaceRecognized = TRUE;
  1261. #else
  1262. // /No-default-namespace files go to the old renderer so we should
  1263. // never encounter this condition:
  1264. HX_ASSERT(m_pSmilDocRenderer->m_pSmilParser->m_pDefaultNamespace);
  1265. #endif
  1266.     }
  1267.     if (!bDefaultNamespaceRecognized)
  1268.     {
  1269. // /We need to auto upgrade if we don't recognize the default
  1270. // namespace.  This can occur under the following conditions
  1271. // (but can not occur if there is no default namespace because
  1272. // those files will all go to the old SMIL 1.0 renderer); note
  1273. // that each of these conditions is a good basis for an AU request
  1274. // except that (3) would best serve our customers if they were
  1275. // notified of the exact reason for the AU request before it
  1276. // happened.
  1277. // /XXXEH- talk to Consumer Group about AU request dialog boxes
  1278. // showing more info.
  1279. // (1) SMIL 3.0 or higher namespace is specified (or whatever
  1280. //     version of SMIL was undefined at the time this renderer was
  1281. //     compiled).
  1282. // (2) Some proprietary namespace that might be handled by some
  1283. //     non-RealNetworks plug-in (or by another RN SMIL renderer).
  1284. // (3) if someone misspells the default namespace that this renderer
  1285. //     otherwise would recognize.
  1286. HX_ASSERT(1);
  1287. IHXUpgradeCollection* pUpColl = NULL;
  1288. if(m_pPlayer &&
  1289.    (HXR_OK == m_pPlayer->QueryInterface(IID_IHXUpgradeCollection,
  1290. (void**)&pUpColl)))
  1291. {
  1292.     CHXBuffer* pBuffer = new CHXBuffer;
  1293.     pBuffer->AddRef();
  1294.     pBuffer->SetSize(strlen(SMIL20_AND_UP_STREAM_MIME_TYPE) +
  1295.     strlen(pDefaultNamespace) + 1 + 1);
  1296.     char* pBuf = (char*)pBuffer->GetBuffer();
  1297.     strcpy(pBuf, SMIL20_AND_UP_STREAM_MIME_TYPE); /* Flawfinder: ignore */
  1298.     strcat(pBuf, "."); /* Flawfinder: ignore */
  1299.     strcat(pBuf, pDefaultNamespace); /* Flawfinder: ignore */
  1300.     pUpColl->Add(eUT_Required, pBuffer, 0, 0);
  1301.     HX_RELEASE(pBuffer);
  1302.     HX_RELEASE(pUpColl);
  1303. }
  1304. return HXR_FAIL;
  1305.     }
  1306. }
  1307. HX_RELEASE(pBuffer);
  1308. if(HXR_OK != rc)
  1309. {
  1310.     // XML parsing error
  1311.     UINT32 ulLineNumber = 0;
  1312.     UINT32 ulColumnNumber = 0;
  1313.     IHXBuffer* pErrorText = NULL;
  1314.     m_pSmilDocRenderer->getErrorInfo(ulLineNumber,
  1315. ulColumnNumber, pErrorText);
  1316.     const char* pActualErrorText = NULL;
  1317.     if(pErrorText)
  1318.     {
  1319. pActualErrorText = (const char*)pErrorText->GetBuffer();
  1320.     }
  1321.     CSmilXMLSyntaxErrorHandler errHandler(m_pContext);
  1322.     errHandler.ReportError(rc, pActualErrorText, ulLineNumber);
  1323.     HX_RELEASE(pErrorText);
  1324. }
  1325. else if(bLastPacket)
  1326. {
  1327.     HX_ASSERT(!m_bInMetadata);
  1328.     m_bInMetadata = FALSE;
  1329.     //[SMIL 1.0 compliance] Handle error from setDocument()
  1330.     // otherwise it "plays" (nothing for 20 seconds) when it
  1331.     // should halt under error conditions:
  1332.     rc = m_pSmilDocRenderer->setDocument(m_pURLFragment);
  1333. }
  1334.     }
  1335.     return rc;
  1336. }
  1337. void
  1338. CSmilRenderer::generatePreFix()
  1339. {
  1340.     // get the protocol/server for later...
  1341.     IHXStreamSource* pSource = 0;
  1342.     m_pStream->GetSource(pSource);
  1343.     HX_ASSERT(pSource);
  1344.     if (!pSource)
  1345.     {
  1346. return;
  1347.     }
  1348.     const char* pURL = pSource->GetURL();
  1349.     HX_ASSERT(pURL);
  1350.     
  1351.     if (!pURL)
  1352.     {
  1353. return;
  1354.     }
  1355.     CHXURL::GeneratePrefixRootFragment(pURL, m_urlPrefix, m_urlRoot, m_pURLFragment);
  1356.     HX_RELEASE(pSource);
  1357.     return;
  1358. }
  1359. HX_RESULT
  1360. CSmilRenderer::SmilDocTrackDurationSet(UINT32 ulGroupIndex,
  1361. UINT32 ulTrackIndex, UINT32 ulDuration, UINT32 ulDelay, BOOL bIsLive)
  1362. {
  1363.     HX_RESULT rc = HXR_FAIL;
  1364.     if (m_pSmilDocRenderer)
  1365.     {
  1366. rc = m_pSmilDocRenderer->TrackDurationSet(ulGroupIndex, ulTrackIndex,
  1367. ulDuration, ulDelay, bIsLive);
  1368.     }
  1369.     return rc;
  1370. }
  1371. HX_RESULT
  1372. CSmilRenderer::SmilDocRepeatedTrackDurationSet(const char* pID,
  1373. UINT32 ulDuration, BOOL bIsLive)
  1374. {
  1375.     HX_RESULT rc = HXR_FAIL;
  1376.     if (m_pSmilDocRenderer)
  1377.     {
  1378. rc = m_pSmilDocRenderer->RepeatedTrackDurationSet(pID, ulDuration,
  1379. bIsLive);
  1380.     }
  1381.     return rc;
  1382. }
  1383. HX_RESULT
  1384. CSmilRenderer::SmilDocTrackUpdated(UINT32 ulGroupIndex, UINT32 ulTrackIndex,
  1385. IHXValues* pValues)
  1386. {
  1387.     HX_RESULT rc = HXR_FAIL;
  1388.     if (m_pSmilDocRenderer)
  1389.     {
  1390. rc = m_pSmilDocRenderer->TrackUpdated(ulGroupIndex, ulTrackIndex, pValues);
  1391.     }
  1392.     return rc;
  1393. }
  1394. HX_RESULT
  1395. CSmilRenderer::SmilDocRendererInitialized(IHXRenderer* pRend,
  1396. IUnknown* pStream, IHXValues* pInfo)
  1397. {
  1398.     HX_RESULT rc = HXR_FAIL;
  1399.     if (m_pSmilDocRenderer)
  1400.     {
  1401. rc = m_pSmilDocRenderer->RendererInitialized(pRend, pStream, pInfo);
  1402.     }
  1403.     return rc;
  1404. }
  1405. HX_RESULT
  1406. CSmilRenderer::SmilDocRendererClosed(IHXRenderer* pRend, IHXValues* pInfo)
  1407. {
  1408.     HX_RESULT rc = HXR_FAIL;
  1409.     if (m_pSmilDocRenderer)
  1410.     {
  1411. rc = m_pSmilDocRenderer->RendererClosed(pRend, pInfo);
  1412.     }
  1413.     return rc;
  1414. }
  1415. HX_RESULT
  1416. CSmilRenderer::SmilDocGroupAdded(UINT16 uGroupIndex, IHXGroup* pGroup)
  1417. {
  1418.     HX_RESULT rc = HXR_FAIL;
  1419.     if (m_pSmilDocRenderer)
  1420.     {
  1421. rc = m_pSmilDocRenderer->GroupAdded(uGroupIndex, pGroup);
  1422.     }
  1423.     return rc;
  1424. }
  1425. HX_RESULT
  1426. CSmilRenderer::SmilDocGroupRemoved(UINT16 uGroupIndex, IHXGroup* pGroup)
  1427. {
  1428.     HX_RESULT rc = HXR_FAIL;
  1429.     if (m_pSmilDocRenderer)
  1430.     {
  1431. rc = m_pSmilDocRenderer->GroupRemoved(uGroupIndex, pGroup);
  1432.     }
  1433.     return rc;
  1434. }
  1435. HX_RESULT
  1436. CSmilRenderer::SmilDocAllGroupsRemoved()
  1437. {
  1438.     HX_RESULT rc = HXR_FAIL;
  1439.     if (m_pSmilDocRenderer)
  1440.     {
  1441. rc = m_pSmilDocRenderer->AllGroupsRemoved();
  1442.     }
  1443.     return rc;
  1444. }
  1445. HX_RESULT
  1446. CSmilRenderer::SmilDocTrackAdded(UINT16 uGroupIndex, UINT16 uTrackIndex,
  1447. IHXValues* pTrack)
  1448. {
  1449.     HX_RESULT rc = HXR_FAIL;
  1450.     if (m_pSmilDocRenderer)
  1451.     {
  1452. rc = m_pSmilDocRenderer->TrackAdded(uGroupIndex, uTrackIndex, pTrack);
  1453.     }
  1454.     return rc;
  1455. }
  1456. HX_RESULT
  1457. CSmilRenderer::SmilDocTrackRemoved(UINT16 uGroupIndex, UINT16 uTrackIndex,
  1458. IHXValues* pTrack)
  1459. {
  1460.     HX_RESULT rc = HXR_FAIL;
  1461.     if (m_pSmilDocRenderer)
  1462.     {
  1463. rc = m_pSmilDocRenderer->TrackRemoved(uGroupIndex, uTrackIndex, pTrack);
  1464.     }
  1465.     return rc;
  1466. }
  1467. HX_RESULT
  1468. CSmilRenderer::SmilDocTrackStarted(UINT16 uGroupIndex, UINT16 uTrackIndex,
  1469.     IHXValues* pTrack)
  1470. {
  1471.     HX_RESULT rc = HXR_FAIL;
  1472.     if (m_pSmilDocRenderer)
  1473.     {
  1474. rc = m_pSmilDocRenderer->TrackStarted(uGroupIndex, uTrackIndex, pTrack);
  1475.     }
  1476.     return rc;
  1477. }
  1478. HX_RESULT
  1479. CSmilRenderer::SmilDocTrackStopped(UINT16 uGroupIndex, UINT16 uTrackIndex,
  1480. IHXValues* pTrack)
  1481. {
  1482.     HX_RESULT rc = HXR_FAIL;
  1483.     if (m_pSmilDocRenderer)
  1484.     {
  1485. rc = m_pSmilDocRenderer->TrackStopped(uGroupIndex, uTrackIndex, pTrack);
  1486.     }
  1487.     return rc;
  1488. }
  1489. HX_RESULT
  1490. CSmilRenderer::SmilDocCurrentGroupSet(UINT16 uGroupIndex, IHXGroup* pGroup)
  1491. {
  1492.     HX_RESULT rc = HXR_FAIL;
  1493.     if (m_pSmilDocRenderer)
  1494.     {
  1495. rc = m_pSmilDocRenderer->CurrentGroupSet(uGroupIndex, pGroup);
  1496.     }
  1497.     return rc;
  1498. }