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

Symbian

开发平台:

Visual C++

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