hxplay.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:277k
- /* ***** BEGIN LICENSE BLOCK *****
- * Version: RCSL 1.0/RPSL 1.0
- *
- * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file, are
- * subject to the current version of the RealNetworks Public Source License
- * Version 1.0 (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the RealNetworks Community Source License Version 1.0
- * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
- * in which case the RCSL will apply. You may also obtain the license terms
- * directly from RealNetworks. You may not use this file except in
- * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
- * applicable to this file, the RCSL. Please see the applicable RPSL or
- * RCSL for the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the portions
- * it created.
- *
- * This file, and the files included with this file, is distributed and made
- * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- #include "hxtypes.h"
- #if (defined( _WIN32 ) || defined( _WINDOWS )) && !defined(WIN32_PLATFORM_PSPC)
- #include <winsock2.h>
- #endif /* defined( _WIN32 ) || defined( _WINDOWS ) */
- #include "hxcom.h"
- #include "hxmime.h"
- #include "dbcs.h"
- #include "chxxtype.h"
- #include "hxresult.h"
- #ifndef _WINCE
- #include "hlxclib/signal.h"
- #endif
- #include "conn.h"
- #if defined( _WIN32 ) || defined( _WINDOWS )
- #include "platform/win/win_net.h"
- #elif defined (_MACINTOSH)
- #include "mac_net.h"
- #elif defined (_UNIX)
- #include "unix_net.h"
- #elif defined(__TCS__)
- #include "platform/tm1/tm1_net.h"
- #endif // defined( _WIN32 ) || defined( _WINDOWS )
- #include "hxcomm.h"
- #include "ihxpckts.h"
- #include "hxfiles.h"
- #include "hxformt.h"
- #include "hxengin.h"
- #include "hxcore.h"
- #include "hxprefs.h"
- #include "hxpref.h"
- #include "hxclsnk.h"
- #include "hxpends.h"
- #include "hxhyper.h"
- #include "playhpnv.h"
- #include "hxmon.h"
- #if defined(HELIX_FEATURE_ASM)
- #include "hxasm.h"
- #include "hxsmbw.h"
- #include "createbwman.h"
- #endif /* HELIX_FEATURE_ASM */
- #include "hxplugn.h"
- #include "chxeven.h"
- #include "chxelst.h"
- #include "strminfo.h"
- #if defined(HELIX_FEATURE_MEDIAMARKER)
- #include "hxmmrkr.h"
- #endif /* #if defined(HELIX_FEATURE_MEDIAMARKER) */
- #if defined(HELIX_FEATURE_EVENTMANAGER)
- #include "hxinter.h"
- #endif /* #if defined(HELIX_FEATURE_EVENTMANAGER) */
- #include "hxslist.h"
- #include "hxmap.h"
- #include "hxstrutl.h"
- //#include "plgnhand.h"
- #include "hxrquest.h"
- #include "chxelst.h"
- #include "hxbsrc.h"
- #include "hxsrc.h"
- #include "hxflsrc.h"
- #include "hxntsrc.h"
- #include "hxrendr.h"
- #include "hxwin.h"
- #include "hxstrm.h"
- #include "hxcleng.h"
- #include "timeline.h"
- #include "hxstring.h"
- #include "timeval.h"
- #include "hxerror.h"
- #include "sinkctl.h"
- #include "upgrdcol.h"
- #include "chxphook.h"
- #include "hxgroup.h"
- #include "basgroup.h"
- #include "advgroup.h"
- // temporary
- //#define DEBUG_LOG_INFO 1
- #include "hxstat.h"
- #include "auderrs.h"
- #include "hxausvc.h"
- #include "hxaudses.h"
- #include "hxaudply.h"
- #include "hxplay.h"
- #include "hxplugn.h"
- #include "hxtick.h"
- #include "srcinfo.h"
- #include "nxtgrmgr.h"
- #include "prefmgr.h"
- #include "srcinfo.h"
- #include "errdbg.h"
- #include "hxthread.h"
- #include "hxxrsmg.h"
- #include "hxresmgr.h"
- #include "portaddr.h"
- #if defined(HELIX_FEATURE_SMARTERNETWORK)
- #include "preftran.h"
- #endif /* HELIX_FEATURE_SMARTERNETWORK */
- #include "cookies.h"
- #include "viewport.h"
- #if defined(HELIX_FEATURE_MEDIAMARKER)
- #include "mediamrk.h"
- #endif /* #if defined(HELIX_FEATURE_MEDIAMARKER) */
- #if defined(HELIX_FEATURE_EVENTMANAGER)
- #include "eventmgr.h"
- #endif /* #if defined(HELIX_FEATURE_EVENTMANAGER) */
- #include "hxtac.h"
- #if defined(_STATICALLY_LINKED) || !defined(HELIX_FEATURE_PLUGINHANDLER2)
- #include "hxpluginmanager.h"
- #else
- #include "plghand2.h"
- #endif /* _STATICALLY_LINKED */
- //#include "../dcondev/dcon.h"
- //BOOL g_bRahulLog = FALSE;
- #if defined(_MACINTOSH) || defined(_MAC_UNIX)
- #include "platform/mac/hx_moreprocesses.h"
- #endif
- #ifdef _MACINTOSH
- #include "hxmm.h"
- #endif
- #ifdef _UNIX
- #include "unix_net.h"
- #endif
- #include "sitemgr.h"
- #include "hxheap.h"
- #ifdef _DEBUG
- #undef HX_THIS_FILE
- static const char HX_THIS_FILE[] = __FILE__;
- #endif
- #ifdef _WIN16
- extern HINSTANCE g_hInstance; // initialized in DLLMAIN.CPP(rmacore.dll)
- #endif
- #if defined(__TCS__)
- #if defined(__cplusplus)
- extern "C" {
- #endif
- void hookRealAudio_ReportError(int err, long errVal);
- #ifdef __cplusplus
- }
- #endif
- #endif
- #define MIN_DELAYBEFORE_START 2000
- #define BEGIN_SYNC_FUDGE_FACTOR 50
- #define MAX_LOOP_EXE_TIME 300 //100
- #define ALLFS 0xFFFFFFFF
- #define GOTOEXITONERROR(theErr, label) if (theErr) goto label
- /* Please add any variables to be re-initialized in the ResetPlayer()
- * function also.
- */
- HXPlayer::HXPlayer() :
- m_pURL (0)
- ,m_lRefCount (0)
- ,m_pPreferences(0)
- ,m_pClientRequestSink(0)
- ,m_pHyperNavigate(0)
- ,m_pRegistry(0)
- ,m_pStats(0)
- ,m_pUpdateStatsCallback(0)
- ,m_ulStatsGranularity(1000)
- ,m_pEngine (0)
- ,m_pPlugin2Handler(0)
- ,m_pAudioPlayer (0)
- ,m_uNumSourcesActive(0)
- ,m_uNumCurrentSourceNotDone(0)
- ,m_bInitialized (FALSE)
- ,m_pPendingTrackList(NULL)
- ,m_ulCurrentPlayTime (0)
- #if defined(_MACINTOSH) || defined(_MAC_UNIX)
- ,m_ulCurrentSystemPlayTime(0)
- #endif
- ,m_ulPresentationDuration(0)
- ,m_ulTimeBeforeSeek (0)
- ,m_ulTimeAfterSeek (0)
- ,m_BufferingReason(BUFFERING_START_UP)
- ,m_pScheduler(0)
- ,m_bIsDone(TRUE)
- ,m_bIsPresentationDone(TRUE)
- ,m_bIsPresentationClosedToBeSent(FALSE)
- ,m_bCoreLocked(FALSE)
- ,m_bPaused(FALSE)
- ,m_bBeginPending(FALSE)
- ,m_pClient(0)
- ,m_ulLowestGranularity(DEFAULT_TIMESYNC_GRANULARITY)
- ,m_bTimelineToBeResumed (FALSE)
- ,m_bIsPlaying(FALSE)
- ,m_bNetInitialized(FALSE)
- ,m_bPrefTransportInitialized(FALSE)
- ,m_bIsFirstBegin(TRUE)
- ,m_bIsFirstBeginPending(FALSE)
- ,m_bIsLive(FALSE)
- ,m_bProcessEventsLocked(FALSE)
- ,m_bTimeSyncLocked(FALSE)
- ,m_bCurrentPresentationClosed(FALSE)
- ,m_LastError(HXR_OK)
- ,m_bInStop(FALSE)
- ,m_bPlayerWithoutSources(FALSE)
- ,m_ulMinimumAudioPreroll(0)
- ,m_ulMinimumTotalPreroll(0)
- ,m_bInternalPauseResume(FALSE)
- ,m_bInternalReset(FALSE)
- ,m_pErrorSinkControl(NULL)
- ,m_pAdviseSink(NULL)
- ,m_pSiteManager(NULL)
- ,m_pSiteSupplier(NULL)
- ,m_pHXPlayerCallback(0)
- ,m_pSetupCallback(0)
- ,m_pAuthenticationCallback(NULL)
- ,m_pHXPlayerInterruptCallback(NULL)
- ,m_nGroupCount(0)
- ,m_nCurrentGroup(0)
- ,m_bContactingDone(FALSE)
- ,m_pUpgradeCollection(NULL)
- ,m_pPacketHookManager(NULL)
- ,m_bIsFirstTimeSync(TRUE)
- ,m_ulFirstTimeSync(0)
- ,m_ulElapsedPauseTime(0)
- ,m_ulLiveSeekTime(0)
- ,m_ulTimeOfPause(0)
- ,m_bLiveSeekToBeDone(FALSE)
- ,m_bFastStartInProgress(FALSE)
- ,m_ulFSBufferingEndTime(0)
- ,m_bAllLocalSources(TRUE)
- ,m_bFSBufferingEnd(FALSE)
- ,m_pGroupManager(NULL)
- ,m_bPartOfNextGroup(FALSE)
- ,m_pNextGroupManager(NULL)
- ,m_pPrefetchManager(NULL)
- ,m_bLastGroup(FALSE)
- ,m_bNextGroupStarted(FALSE)
- ,m_bDidWeDeleteAllEvents(FALSE)
- ,m_bSetupLayoutSiteGroup(TRUE)
- ,m_pCurrentGroup(NULL)
- ,m_bBeginChangeLayoutTobeCalled(TRUE)
- ,m_b100BufferingToBeSent(TRUE)
- ,m_bUserHasCalledBegin(FALSE)
- ,m_bCloseAllRenderersPending(FALSE)
- ,m_uNumSourceToBeInitializedBeforeBegin(0)
- ,m_pCoreMutex(NULL)
- ,m_bSetupToBeDone(FALSE)
- ,m_bPostSetupToBeDone(FALSE)
- ,m_pRequest(NULL)
- ,m_pAltURLs(NULL)
- ,m_bActiveRequest(FALSE)
- ,m_bUseCoreThread(FALSE)
- ,m_bAddLayoutSiteGroupCalled(FALSE)
- ,m_pLastUserString(NULL)
- ,m_pLastMoreInfoURL(NULL)
- ,m_bForceStatsUpdate(FALSE)
- #if defined(HELIX_FEATURE_ASM)
- ,m_pBandwidthMgr(NULL)
- ,m_pASM(NULL)
- #endif
- ,m_pRedirectList(NULL)
- ,m_bPendingAudioPause(FALSE) // currently used ONLY on Mac
- ,m_bPlayStateNotified(FALSE)
- ,m_bResumeOnlyAtSystemTime(FALSE)
- ,m_bSourceMapUpdated(FALSE)
- ,m_pPreferredTransportManager(NULL)
- ,m_pNetInterfaces(NULL)
- ,m_pClientViewSource(NULL)
- ,m_pViewPortManager(NULL)
- ,m_pMediaMarkerManager(NULL)
- ,m_pEventManager(NULL)
- ,m_pClientViewRights(NULL)
- ,m_ulRepeatedRegistryID(0)
- ,m_ulNextGroupRegistryID(0)
- ,m_pCookies(NULL)
- ,m_pParentPlayer(NULL)
- ,m_pChildPlayerList(NULL)
- ,m_bSetModal(FALSE)
- ,m_pPersistentComponentManager(NULL)
- ,m_pAutheticationValues(NULL)
- ,m_bDoRedirect(FALSE)
- ,m_ulActiveSureStreamSource(0)
- ,m_bFastStartCheckDone(FALSE)
- ,m_bFastStart(FALSE)
- ,m_turboPlayOffReason(TP_OFF_BY_UNKNOWN)
- ,m_pMasterTAC(NULL)
- #ifdef _WIN32
- ,m_bScreenSaverActive(0)
- #endif
- ,m_pRecordService(NULL)
- ,m_bRecordServiceEnabled(FALSE)
- /* Please add any variables to be re-initialized in the ResetPlayer()
- * function also.
- */
- {
- m_pSourceMap = new CHXMapPtrToPtr;
- m_pSharedWallClocks = new CHXMapStringToOb;
-
- #if defined(_DEBUG) && defined(DEBUG_LOG_INFO)
- HXStaticStatLog::Open_Write("e:\log.txt");
- #endif // DEBUG_LOG_INFO
- ResetError();
- #if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
- m_pUpdateStatsCallback = new UpdateStatsCallback;
- m_pUpdateStatsCallback->m_pPlayer = this;
- m_pUpdateStatsCallback->AddRef();
- #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
- #if defined (_WIN32) || defined (_MACINTOSH) || defined(THREADS_SUPPORTED)
- m_pHXPlayerCallback = new HXPlayerCallback((void*)this, (fGenericCBFunc)PlayerCallback);
- m_pHXPlayerInterruptCallback = new HXPlayerCallback((void*)this, (fGenericCBFunc)PlayerCallback);
- m_pSetupCallback = new HXPlayerCallback((void*)this, (fGenericCBFunc)SetupCallback);
- ((HXPlayerCallback*)m_pHXPlayerInterruptCallback)->m_bInterrupSafe = TRUE;
- ((HXPlayerCallback*)m_pSetupCallback)->m_bInterrupSafe = TRUE;
- #else
- m_pHXPlayerCallback = new CHXGenericCallback((void*)this, (fGenericCBFunc)PlayerCallback);
- m_pHXPlayerInterruptCallback = new CHXGenericCallback((void*)this, (fGenericCBFunc)PlayerCallback);
- m_pSetupCallback = new CHXGenericCallback((void*)this, (fGenericCBFunc)SetupCallback);
- #endif
- m_pHXPlayerCallback->AddRef();
- m_pHXPlayerInterruptCallback->AddRef();
- m_pSetupCallback->AddRef();
- #if defined(HELIX_FEATURE_AUTHENTICATION)
- m_pAuthenticationCallback = new CHXGenericCallback((void*)this, (fGenericCBFunc)AuthenticationCallback);
- m_pAuthenticationCallback->AddRef();
- #endif /* HELIX_FEATURE_AUTHENTICATION */
- #if defined(HELIX_FEATURE_SINKCONTROL)
- m_pErrorSinkControl = new CHXErrorSinkControl;
- m_pAdviseSink = new CHXAdviseSinkControl;
- #endif /* HELIX_FEATURE_SINKCONTROL */
- #if defined(HELIX_FEATURE_VIDEO)
- m_pSiteManager = new CHXSiteManager();
- #endif /* HELIX_FEATURE_VIDEO */
- #if defined(HELIX_FEATURE_ADVANCEDGROUPMGR)
- m_pGroupManager = new HXAdvancedGroupManager(this);
- #elif defined(HELIX_FEATURE_BASICGROUPMGR)
- m_pGroupManager = new HXBasicGroupManager(this);
- #endif /* HELIX_FEATURE_ADVANCEDGROUPMGR */
- #if defined(HELIX_FEATURE_NEXTGROUPMGR)
- m_pNextGroupManager = new NextGroupManager(this);
- #endif /* HELIX_FEATURE_NEXTGROUPMGR */
- #if defined(HELIX_FEATURE_MASTERTAC)
- m_pMasterTAC = new HXMasterTAC(m_pGroupManager);
- #endif /* HELIX_FEATURE_MASTERTAC */
- #if defined(HELIX_FEATURE_VIEWPORT)
- m_pViewPortManager = new HXViewPortManager(this);
- #endif /* HELIX_FEATURE_VIEWPORT */
- #if defined(HELIX_FEATURE_MEDIAMARKER)
- m_pMediaMarkerManager = new CHXMediaMarkerManager(this);
- if (m_pMediaMarkerManager) m_pMediaMarkerManager->AddRef();
- #endif /* #if defined(HELIX_FEATURE_MEDIAMARKER) */
- #if defined(HELIX_FEATURE_NESTEDMETA)
- m_pPersistentComponentManager = new HXPersistentComponentManager(this);
- #endif /* HELIX_FEATURE_NESTEDMETA */
- HX_ADDREF(m_pErrorSinkControl);
- HX_ADDREF(m_pAdviseSink);
- #if defined(HELIX_FEATURE_VIDEO)
- m_pSiteManager->AddRef();
- #endif /* HELIX_FEATURE_VIDEO */
- #if defined(HELIX_FEATURE_BASICGROUPMGR)
- m_pGroupManager->AddRef();
- m_pGroupManager->AddSink(this);
- #endif /* HELIX_FEATURE_BASICGROUPMGR */
- HX_ADDREF(m_pMasterTAC);
- #if defined(HELIX_FEATURE_VIEWPORT)
- m_pViewPortManager->AddRef();
- #endif /* HELIX_FEATURE_VIEWPORT */
- #if defined(HELIX_FEATURE_ADVANCEDGROUPMGR) && defined(HELIX_FEATURE_MASTERTAC)
- if (m_pGroupManager && m_pMasterTAC)
- {
- m_pGroupManager->SetMasterTAC(m_pMasterTAC);
- }
- #endif /* HELIX_FEATURE_ADVANCEDGROUPMGR && HELIX_FEATURE_MASTERTAC */
- #if defined(HELIX_FEATURE_NESTEDMETA)
- m_pPersistentComponentManager->AddRef();
- if (m_pGroupManager)
- {
- m_pGroupManager->AddSink(m_pPersistentComponentManager);
- }
- #endif /* HELIX_FEATURE_NESTEDMETA */
- #if defined(HELIX_FEATURE_AUTOUPGRADE)
- m_pUpgradeCollection = new HXUpgradeCollection;
- m_pUpgradeCollection->AddRef();
- #endif /* HELIX_FEATURE_AUTOUPGRADE */
- #if defined(HELIX_FEATURE_EVENTMANAGER)
- // Get our own IUnknown interface
- IUnknown* pUnknown = NULL;
- QueryInterface(IID_IUnknown, (void**) &pUnknown);
- if (pUnknown)
- {
- // Initialize the renderer event manager
- m_pEventManager = new CRendererEventManager(pUnknown);
- if (m_pEventManager) m_pEventManager->AddRef();
- }
- HX_RELEASE(pUnknown);
- #endif /* #if defined(HELIX_FEATURE_EVENTMANAGER) */
- }
- HXPlayer::~HXPlayer()
- {
- CloseAllRenderers(m_nCurrentGroup);
- ResetPlayer();
- Close();
- HX_DELETE(m_pSourceMap);
- HX_DELETE(m_pSharedWallClocks);
- }
- /////////////////////////////////////////////////////////////////////////
- // Method:
- // IUnknown::QueryInterface
- // Purpose:
- // Implement this to export the interfaces supported by your
- // object.
- //
- STDMETHODIMP HXPlayer::QueryInterface(REFIID riid, void** ppvObj)
- {
- #if defined(HELIX_FEATURE_PACKETHOOKMGR)
- // create the following objects only if needed
- if (!m_pPacketHookManager && IsEqualIID(riid, IID_IHXPacketHookManager))
- {
- m_pPacketHookManager = new PacketHookManager(this);
- if (m_pPacketHookManager)
- {
- m_pPacketHookManager->AddRef();
- }
- }
- #endif /* HELIX_FEATURE_PACKETHOOKMGR */
- QInterfaceList qiList[] =
- {
- { GET_IIDHANDLE(IID_IHXPlayer), (IHXPlayer*)this },
- { GET_IIDHANDLE(IID_IHXPlayer2), (IHXPlayer2*)this },
- { GET_IIDHANDLE(IID_IHXPendingStatus), (IHXPendingStatus*)this },
- #if defined(HELIX_FEATURE_AUTHENTICATION)
- { GET_IIDHANDLE(IID_IHXAuthenticationManager), (IHXAuthenticationManager*)this },
- { GET_IIDHANDLE(IID_IHXAuthenticationManager2), (IHXAuthenticationManager2*)this },
- #endif /* HELIX_FEATURE_AUTHENTICATION */
- { GET_IIDHANDLE(IID_IHXGroupSink), (IHXGroupSink*)this },
- { GET_IIDHANDLE(IID_IHXAudioPlayerResponse), (IHXAudioPlayerResponse*)this },
- { GET_IIDHANDLE(IID_IHXRegistryID), (IHXRegistryID*)this },
- { GET_IIDHANDLE(IID_IHXErrorMessages), (IHXErrorMessages*)this },
- { GET_IIDHANDLE(IID_IHXLayoutSiteGroupManager), (IHXLayoutSiteGroupManager*)this },
- #if defined(HELIX_FEATURE_NESTEDMETA)
- { GET_IIDHANDLE(IID_IHXPersistenceManager), (IHXPersistenceManager*)this },
- #endif /* HELIX_FEATURE_NESTEDMETA */
- { GET_IIDHANDLE(IID_IHXDriverStreamManager), (IHXDriverStreamManager*)this },
- { GET_IIDHANDLE(IID_IHXRendererUpgrade), (IHXRendererUpgrade*)this },
- { GET_IIDHANDLE(IID_IHXInternalReset), (IHXInternalReset*)this },
- { GET_IIDHANDLE(IID_IHXPlayerState), (IHXPlayerState*)this },
- #if defined(HELIX_FEATURE_PLAYERNAVIGATOR)
- { GET_IIDHANDLE(IID_IHXPlayerNavigator), (IHXPlayerNavigator*)this },
- #endif /* HELIX_FEATURE_PLAYERNAVIGATOR */
- { GET_IIDHANDLE(IID_IHXClientStatisticsGranularity), (IHXClientStatisticsGranularity*)this },
- { GET_IIDHANDLE(IID_IHXPlayerPresentation), (IHXPlayerPresentation*)this },
- #if defined(HELIX_FEATURE_RECORDCONTROL)
- { GET_IIDHANDLE(IID_IHXRecordManager), (IHXRecordManager*)this },
- #endif /* HELIX_FEATURE_RECORDCONTROL */
- { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXPlayer*)this },
- { GET_IIDHANDLE(IID_IHXOverrideDefaultServices), (IHXOverrideDefaultServices*)this },
- };
- HX_RESULT res = ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
-
- // if it succeeded, return immediately...
- if (res == HXR_OK)
- {
- return res;
- }
- // ...otherwise continue onward
-
- if (m_pClientViewSource &&
- IsEqualIID(riid, IID_IHXViewSourceCommand))
- {
- AddRef();
- *ppvObj = (IHXViewSourceCommand*)this;
- return HXR_OK;
- }
- else if (m_pErrorSinkControl &&
- m_pErrorSinkControl->QueryInterface(riid, ppvObj) == HXR_OK)
- {
- return HXR_OK;
- }
- else if (m_pAdviseSink &&
- m_pAdviseSink->QueryInterface(riid, ppvObj) == HXR_OK)
- {
- return HXR_OK;
- }
- else if (m_pAudioPlayer &&
- m_pAudioPlayer->QueryInterface(riid, ppvObj) == HXR_OK)
- {
- return HXR_OK;
- }
- #if defined(HELIX_FEATURE_PREFERENCES)
- else if (m_pPreferences &&
- m_pPreferences->QueryInterface(riid, ppvObj) == HXR_OK)
- {
- return HXR_OK;
- }
- #endif /* HELIX_FEATURE_PREFERENCES */
- #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
- else if (m_pHyperNavigate &&
- m_pHyperNavigate->QueryInterface(riid, ppvObj) == HXR_OK)
- {
- return HXR_OK;
- }
- #endif /* HELIX_FEATURE_HYPER_NAVIGATE */
- #if defined(HELIX_FEATURE_ASM)
- /* m_pASM will be available on a per player basis ONLY under Load testing */
- else if (m_pASM &&
- m_pASM->QueryInterface(riid, ppvObj) == HXR_OK)
- {
- return HXR_OK;
- }
- #endif /* HELIX_FEATURE_ASM */
- #if defined(HELIX_FEATURE_VIDEO)
- else if (m_pSiteManager &&
- m_pSiteManager->QueryInterface(riid, ppvObj) == HXR_OK)
- {
- return HXR_OK;
- }
- #endif /* HELIX_FEATURE_VIDEO */
- #if defined(HELIX_FEATURE_AUTOUPGRADE)
- else if (m_pUpgradeCollection &&
- m_pUpgradeCollection->QueryInterface(riid, ppvObj) == HXR_OK)
- {
- return HXR_OK;
- }
- #endif /* HELIX_FEATURE_AUTOUPGRADE */
- #if defined(HELIX_FEATURE_PACKETHOOKMGR)
- else if (m_pPacketHookManager &&
- m_pPacketHookManager->QueryInterface(riid, ppvObj) == HXR_OK)
- {
- return HXR_OK;
- }
- #endif /* HELIX_FEATURE_PACKETHOOKMGR */
- #if defined(HELIX_FEATURE_BASICGROUPMGR)
- else if (m_pGroupManager &&
- m_pGroupManager->QueryInterface(riid, ppvObj) == HXR_OK)
- {
- return HXR_OK;
- }
- #endif /* HELIX_FEATURE_BASICGROUPMGR */
- else if (m_pViewPortManager &&
- m_pViewPortManager->QueryInterface(riid, ppvObj) == HXR_OK)
- {
- return HXR_OK;
- }
- #if defined(HELIX_FEATURE_MEDIAMARKER)
- else if (m_pMediaMarkerManager &&
- m_pMediaMarkerManager->QueryInterface(riid, ppvObj) == HXR_OK)
- {
- return HXR_OK;
- }
- #endif /* #if defined(HELIX_FEATURE_MEDIAMARKER) */
- #if defined(HELIX_FEATURE_EVENTMANAGER)
- else if (m_pEventManager &&
- m_pEventManager->QueryInterface(riid, ppvObj) == HXR_OK)
- {
- return HXR_OK;
- }
- #endif /* #if defined(HELIX_FEATURE_EVENTMANAGER) */
- #if defined(HELIX_FEATURE_NESTEDMETA)
- else if (m_pPersistentComponentManager &&
- m_pPersistentComponentManager->QueryInterface(riid, ppvObj) == HXR_OK)
- {
- return HXR_OK;
- }
- #endif /* HELIX_FEATURE_NESTEDMETA */
- else if (m_pPlugin2Handler &&
- m_pPlugin2Handler->QueryInterface(riid, ppvObj) == HXR_OK)
- {
- return HXR_OK;
- }
- else if (m_pClient &&
- m_pClient->QueryInterface(riid, ppvObj) == HXR_OK)
- {
- return HXR_OK;
- }
- else if (m_pEngine &&
- m_pEngine->QueryInterface(riid, ppvObj) == HXR_OK)
- {
- return HXR_OK;
- }
- /* DO NOT ADD ANY MROE QIs HERE. ADD IT BEFORE m_pClient QI*/
- *ppvObj = NULL;
- return HXR_NOINTERFACE;
- }
- /////////////////////////////////////////////////////////////////////////
- // Method:
- // IUnknown::AddRef
- // Purpose:
- // Everyone usually implements this the same... feel free to use
- // this implementation.
- //
- STDMETHODIMP_(ULONG32) HXPlayer::AddRef()
- {
- return InterlockedIncrement(&m_lRefCount);
- }
- /////////////////////////////////////////////////////////////////////////
- // Method:
- // IUnknown::Release
- // Purpose:
- // Everyone usually implements this the same... feel free to use
- // this implementation.
- //
- STDMETHODIMP_(ULONG32) HXPlayer::Release()
- {
- if (InterlockedDecrement(&m_lRefCount) > 0)
- {
- return m_lRefCount;
- }
- if(m_lRefCount == 0)
- {
- delete this;
- }
- return 0;
- }
- // *** IHXPlayer methods ***
- /************************************************************************
- * Method:
- * IHXPlayer::GetClientEngine
- * Purpose:
- * Get the interface to the client engine object of which the player
- * is a part of.
- *
- */
- STDMETHODIMP HXPlayer::GetClientEngine(IHXClientEngine* &pEngine)
- {
- pEngine = m_pEngine;
- if (pEngine)
- {
- pEngine->AddRef();
- }
- return HXR_OK;
- }
- /************************************************************************
- * Method:
- * IHXPlayer::Begin
- * Purpose:
- * Tell the player to begin playback of all its sources.
- *
- */
- STDMETHODIMP HXPlayer::Begin(void)
- {
- HX_RESULT theErr = HXR_OK;
- m_bCoreLocked = TRUE;
- m_pCoreMutex->Lock();
- theErr = BeginPlayer();
- m_pCoreMutex->Unlock();
- m_bCoreLocked = FALSE;
- return theErr;
- }
- HX_RESULT
- HXPlayer::BeginPlayer(void)
- {
- HX_RESULT theErr = HXR_OK;
- m_bUserHasCalledBegin = TRUE;
- m_bFastStartInProgress = FALSE;
- if (!m_bInternalPauseResume && !m_bIsFirstBegin && !m_bPaused)
- {
- return HXR_OK;
- }
- if (m_bIsLive && m_bPaused && m_bLiveSeekToBeDone)
- {
- m_ulElapsedPauseTime = CALCULATE_ELAPSED_TICKS(m_ulTimeOfPause, HX_GET_TICKCOUNT());
- /* This is an internal seek due to live pause */
- theErr = SeekPlayer(m_ulLiveSeekTime + m_ulElapsedPauseTime);
- }
- m_bPaused = FALSE;
- if (m_bIsFirstBegin)
- {
- UpdateSourceActive();
- }
- if (!theErr)
- {
- theErr = UpdateStatistics();
- }
- if (!theErr)
- {
- UpdateCurrentPlayTime( m_pAudioPlayer->GetCurrentPlayBackTime() );
- }
- /* Unregister all the sources that are not currently active */
- UnregisterNonActiveSources();
- if (!m_bIsDone)
- {
- CheckSourceRegistration();
- CHXMapPtrToPtr::Iterator ndxSources = m_pSourceMap->Begin();
- /* Check if we are done. This may be TRUE for empty files */
- for (; !theErr && ndxSources != m_pSourceMap->End(); ++ndxSources)
- {
- SourceInfo* pSourceInfo = (SourceInfo*) (*ndxSources);
- theErr = pSourceInfo->Begin();
- }
- }
- /* Only send this OnBegin()'s if not the first begin. In the case
- * of the first begin, these are actually sent after the header's
- * arrive...
- */
- if (!theErr && !m_bIsFirstBegin && !m_bInternalPauseResume && !m_bInternalReset && m_pAdviseSink)
- {
- m_pAdviseSink->OnBegin(m_ulCurrentPlayTime);
- }
- m_bIsFirstBegin = FALSE;
- m_bBeginPending = TRUE;
- m_bFastStartInProgress = FALSE;
- if (!m_ToBeginRendererList.IsEmpty())
- {
- CheckBeginList();
- }
- return (theErr);
- }
- /************************************************************************
- * Method:
- * IHXPlayer::Stop
- * Purpose:
- * Tell the player to stop playback of all its sources.
- *
- */
- STDMETHODIMP HXPlayer::Stop(void)
- {
- // we want to protect against the TLC opening another URL
- if (m_bSetModal)
- {
- return HXR_OK;
- }
- m_bCoreLocked = TRUE;
- m_pCoreMutex->Lock();
- StopPlayer(END_STOP);
- m_pCoreMutex->Unlock();
- m_bCoreLocked = FALSE;
- return HXR_OK;
- }
- void
- HXPlayer::StopPlayer(EndCode endCode)
- {
- StopAllStreams(endCode);
- /* Reset player condition */
- ResetPlayer();
- }
- /************************************************************************
- * Method:
- * IHXPlayer::Pause
- * Purpose:
- * Tell the player to pause playback of all its sources.
- *
- */
- STDMETHODIMP HXPlayer::Pause(void)
- {
- HX_RESULT theErr = HXR_OK;
- m_bCoreLocked = TRUE;
- m_pCoreMutex->Lock();
- theErr = PausePlayer();
- m_pCoreMutex->Unlock();
- m_bCoreLocked = FALSE;
- return theErr;
- }
- HX_RESULT
- HXPlayer::PausePlayer(BOOL bNotifyTLC /* = TRUE*/)
- {
- HX_RESULT theErr = HXR_OK;
- if (m_bIsDone)
- {
- return HXR_UNEXPECTED;
- }
- if (m_bPaused)
- {
- return HXR_OK;
- }
- m_bPaused = TRUE;
- if (m_bIsLive && !(m_bRecordServiceEnabled && m_pRecordService))
- {
- m_bLiveSeekToBeDone = TRUE;
- m_ulLiveSeekTime = m_pAudioPlayer->GetCurrentPlayBackTime();
- m_ulTimeOfPause = HX_GET_TICKCOUNT();
- }
- m_bIsPlaying = FALSE;
- m_bTimelineToBeResumed = TRUE;
- m_pAudioPlayer->Pause();
- CHXMapPtrToPtr::Iterator ndxSource = m_pSourceMap->Begin();
- for (; !theErr && ndxSource != m_pSourceMap->End(); ++ndxSource)
- {
- SourceInfo* pSourceInfo = (SourceInfo*)(*ndxSource);
- theErr = pSourceInfo->Pause();
- }
- /* Send OnPause to advice sink ONLY if it is not an internal Pause */
- if (bNotifyTLC && !m_bInternalPauseResume && !m_bInternalReset && m_pAdviseSink)
- {
- m_pAdviseSink->OnPause(m_ulCurrentPlayTime);
- }
- return (theErr);
- }
- /************************************************************************
- * Method:
- * IHXPlayer::Seek
- * Purpose:
- * Tell the player to seek in the playback timeline of all its
- * sources.
- *
- */
- STDMETHODIMP HXPlayer::Seek(ULONG32 ulTime)
- {
- HX_RESULT theErr = HXR_OK;
- m_bCoreLocked = TRUE;
- m_pCoreMutex->Lock();
- theErr = SeekPlayer(ulTime);
- m_pCoreMutex->Unlock();
- m_bCoreLocked = FALSE;
- return theErr;
- }
- HX_RESULT
- HXPlayer::SeekPlayer(ULONG32 ulTime)
- {
- HX_RESULT theErr = HXR_OK;
- if (m_bIsDone)
- {
- return HXR_UNEXPECTED;
- }
- // do not allow seeking till we have been initialized
- if (!m_bInitialized)
- {
- return HXR_NOT_INITIALIZED;
- }
- /* we do allow internal seek (done during resume after live pause)*/
- if ((m_bIsLive && !m_bLiveSeekToBeDone && !(m_bRecordServiceEnabled && m_pRecordService)) ||
- !AreAllSourcesSeekable())
- {
- /* Add error code for HXR_OPERATION_NOT_ALLOWED*/
- return HXR_FAILED;
- }
- /* Someone called Seek without calling Pause, So we will have to call
- * Pause and Resume internally
- */
- if (!m_bPaused)
- {
- m_bInternalPauseResume = TRUE;
- PausePlayer();
- }
- #if defined(HELIX_FEATURE_NEXTGROUPMGR)
- /* Stop prefetching */
- if (m_pNextGroupManager->GetNumSources() > 0)
- {
- m_pNextGroupManager->StopPreFetch();
- m_bLastGroup = FALSE;
- m_bNextGroupStarted = FALSE;
- }
- #endif /* HELIX_FEATURE_NEXTGROUPMGR */
- m_ulTimeBeforeSeek = m_pAudioPlayer->GetCurrentPlayBackTime();
- m_ulTimeAfterSeek = ulTime;
- UpdateCurrentPlayTime(ulTime);
- m_pAudioPlayer->Seek(ulTime);
- CHXMapPtrToPtr::Iterator ndxSource = m_pSourceMap->Begin();
- for (; !theErr && ndxSource != m_pSourceMap->End(); ++ndxSource)
- {
- SourceInfo* pSourceInfo = (SourceInfo*)(*ndxSource);
- pSourceInfo->Seek(ulTime);
- }
- if (m_pAdviseSink)
- {
- m_pAdviseSink->OnPreSeek(m_ulTimeBeforeSeek, m_ulTimeAfterSeek);
- }
- // change the state of buffering to seek
- if (m_bIsLive)
- {
- m_BufferingReason = BUFFERING_LIVE_PAUSE;
- }
- else
- {
- m_BufferingReason = BUFFERING_SEEK;
- }
- /* Send all pre-seek events to the renderers */
- SendPreSeekEvents();
- ndxSource = m_pSourceMap->Begin();
- for (; !theErr && ndxSource != m_pSourceMap->End();)
- {
- SourceInfo* pSourceInfo = (SourceInfo*)(*ndxSource);
- HXSource * pSource = pSourceInfo->m_pSource;
- // since the map index could be screwed up by the removing of
- // the current node in AdjustSeekOnRepeatedSource()
- ++ndxSource;
- /* pSource should never be NULL */
- HX_ASSERT(pSource);
- if (pSourceInfo->m_bSeekPending || !pSourceInfo->IsInitialized())
- {
- continue;
- }
- /* This will pump all pre-seek packets to the renderer(s) */
- if (pSourceInfo->m_pPeerSourceInfo)
- {
- theErr = AdjustSeekOnRepeatedSource(pSourceInfo, ulTime);
- }
- else
- {
- theErr = pSource->DoSeek(ulTime);
- }
- }
- m_b100BufferingToBeSent = TRUE;
- // reset the player state
- UpdateSourceActive();
- m_bIsDone = FALSE;
- if (!theErr)
- {
- if (m_bInternalPauseResume)
- {
- theErr = Begin();
- m_bInternalPauseResume = FALSE;
- }
- else
- {
- /* Start pre-fetch */
- theErr = StartDownload();
- }
- }
- return (theErr);
- }
- /************************************************************************
- * Method:
- * IHXPlayer::GetSourceCount
- * Purpose:
- * Returns the current number of source instances supported by
- * this player instance.
- */
- STDMETHODIMP_(UINT16) HXPlayer::GetSourceCount()
- {
- /* We may have stopped the sources but not removed from the SourceMap
- * since we need to keep the renderers active till the next URL is
- * opened. In this case, report the current number of active sources
- * as zero.
- */
- if (m_bCloseAllRenderersPending)
- {
- return 0;
- }
- else
- {
- return (UINT16)m_pSourceMap->GetCount();
- }
- }
- /************************************************************************
- * Method:
- * IHXPlayer::GetSource
- * Purpose:
- * Returns the Nth source instance supported by this player.
- */
- STDMETHODIMP HXPlayer::GetSource
- (
- UINT16 nIndex,
- REF(IUnknown*) pUnknown
- )
- {
- pUnknown = NULL;
- if (m_bCloseAllRenderersPending || nIndex >= m_pSourceMap->GetCount())
- {
- return HXR_INVALID_PARAMETER;
- }
- CHXMapPtrToPtr::Iterator ndxSource = m_pSourceMap->Begin();
- for (UINT16 i = 0; i < nIndex; i++)
- {
- ++ndxSource;
- }
- SourceInfo* pSourceInfo = (SourceInfo*)(*ndxSource);
- HX_ASSERT(pSourceInfo);
- HXSource* pSource = pSourceInfo->m_pSource;
- if(!pSource)
- {
- pUnknown = NULL;
- return HXR_UNEXPECTED;
- }
- return pSource ? pSource->QueryInterface(IID_IUnknown,(void**)&pUnknown) : HXR_FAIL;
- }
- /************************************************************************
- * Method:
- * IHXPlayer::GetClientContext
- * Purpose:
- * Called by the get the client context for this player. This is
- * traditionally to determine called by top level client application.
- */
- STDMETHODIMP HXPlayer::GetClientContext
- (
- REF(IUnknown*) pUnknown
- )
- {
- pUnknown = m_pClient;
- if (m_pClient)
- {
- m_pClient->AddRef();
- }
- return HXR_OK;
- }
- /************************************************************************
- * Method:
- * IHXPlayer::SetClientContext
- * Purpose:
- * Called by the client to install itself as the provider of client
- * services to the core. This is traditionally called by the top
- * level client application.
- */
- STDMETHODIMP HXPlayer::SetClientContext(IUnknown* pUnknown)
- {
- if (m_pClient) return HXR_UNEXPECTED;
- if (!pUnknown) return HXR_UNEXPECTED;
- m_pClient = pUnknown;
- m_pClient->AddRef();
- /* Override Default objects */
- #if defined(HELIX_FEATURE_PREFERENCES)
- IHXPreferences* pPreferences = 0;
- if (HXR_OK == m_pClient->QueryInterface(IID_IHXPreferences, (void**) &pPreferences) ||
- HXR_OK == m_pEngine->QueryInterface(IID_IHXPreferences, (void**) &pPreferences))
- {
- HX_RELEASE(m_pPreferences);
- m_pPreferences = pPreferences;
- }
- #endif /* HELIX_FEATURE_PREFERENCES */
- #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
- IHXHyperNavigate* pHyperNavigate = NULL;
- IHXHyperNavigateWithContext* pHyperNavigateWithContext = NULL;
- m_pClient->QueryInterface(IID_IHXHyperNavigateWithContext,
- (void**) &pHyperNavigateWithContext);
- m_pClient->QueryInterface(IID_IHXHyperNavigate, (void**) &pHyperNavigate);
- if (pHyperNavigate == NULL)
- {
- m_pEngine->QueryInterface(IID_IHXHyperNavigate, (void**) &pHyperNavigate);
- }
- HX_ASSERT(pHyperNavigate != NULL);
- if (pHyperNavigate || pHyperNavigateWithContext)
- {
- HX_ASSERT(m_pHyperNavigate == NULL);
- HX_RELEASE(m_pHyperNavigate);
- //
- // Create new hypernaviate interface that knows how to interpret commands.
- //
- PlayerHyperNavigate* pPlayerHyperNavigate = new PlayerHyperNavigate;
- // override the default hypernavigate interface with one that can interpret commands.
- pPlayerHyperNavigate->AddRef();
- pPlayerHyperNavigate->Init((IHXPlayer*)this, pHyperNavigate, pHyperNavigateWithContext);
- m_pHyperNavigate = pPlayerHyperNavigate;
- // free memory
- HX_RELEASE(pHyperNavigate);
- HX_RELEASE(pHyperNavigateWithContext);
- }
- #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
- #if defined(HELIX_FEATURE_VIDEO)
- IHXSiteSupplier* pSiteSupplier = 0;
- if (HXR_OK == m_pClient->QueryInterface(IID_IHXSiteSupplier, (void**) &pSiteSupplier))
- {
- HX_RELEASE(m_pSiteSupplier);
- m_pSiteSupplier = pSiteSupplier;
- }
- #endif /* HELIX_FEATURE_VIDEO */
- m_pClient->QueryInterface(IID_IHXClientRequestSink, (void**) &m_pClientRequestSink);
- /* For load testing, we have ASM Manager on a per player basis */
- #if defined(HELIX_FEATURE_ASM)
- BOOL bLoadTest = FALSE;
- ReadPrefBOOL(m_pPreferences, "LoadTest", bLoadTest);
- if (bLoadTest)
- {
- HX_ASSERT(m_pASM == NULL);
- m_pASM = CreateBandwidthManager();
- if (m_pASM)
- {
- m_pASM->AddRef();
- HX_RELEASE(m_pBandwidthMgr);
- m_pASM->QueryInterface(IID_IHXBandwidthManager,
- (void**) &m_pBandwidthMgr);
- }
- }
- #endif /* HELIX_FEATURE_ASM */
- return HXR_OK;
- }
- /************************************************************************
- * Method:
- * HXPlayer::Init
- * Purpose:
- * Get the interface to the client engine object of which the player
- * is a part of.
- *
- */
- STDMETHODIMP HXPlayer::Init(IHXClientEngine* pEngine,
- UINT32 unRegistryID,
- CHXAudioPlayer* pAudioPlayer)
- {
- HX_RESULT theErr = HXR_OK;
- IHXBuffer* pPlayerRegName = NULL;
- m_pEngine = (HXClientEngine *) pEngine;
- m_pAudioPlayer = pAudioPlayer;
- m_pCoreMutex = m_pEngine->GetCoreMutex();
- m_pEngine->m_pPlugin2Handler->QueryInterface(IID_IHXPlugin2Handler,
- (void**)&m_pPlugin2Handler);
- if (m_pEngine)
- {
- m_pEngine->AddRef();
- #if defined(HELIX_FEATURE_SINKCONTROL)
- if (m_pAdviseSink)
- {
- m_pAdviseSink->Init(m_pEngine);
- }
- if (m_pErrorSinkControl)
- {
- m_pErrorSinkControl->Init(m_pEngine);
- }
- #endif /* HELIX_FEATURE_SINKCONTROL */
- theErr = m_pEngine->QueryInterface(IID_IHXScheduler,
- (void**) &m_pScheduler);
- #if defined(HELIX_FEATURE_ASM)
- m_pEngine->QueryInterface(IID_IHXBandwidthManager,
- (void**) &m_pBandwidthMgr);
- #endif /* HELIX_FEATURE_ASM */
- m_pEngine->QueryInterface(IID_IHXClientViewSource,
- (void**)&m_pClientViewSource);
- m_pEngine->QueryInterface(IID_IHXClientViewRights,
- (void**)&m_pClientViewRights);
- m_pEngine->QueryInterface(IID_IHXPreferredTransportManager,
- (void**)&m_pPreferredTransportManager);
- m_pEngine->QueryInterface(IID_IHXNetInterfaces,
- (void**)&m_pNetInterfaces);
- #if defined(HELIX_FEATURE_REGISTRY)
- // create registry entries
- if (HXR_OK != m_pEngine->QueryInterface(IID_IHXRegistry, (void**)&m_pRegistry))
- {
- m_pRegistry = NULL;
- }
- else
- #endif /* HELIX_FEATURE_REGISTRY */
- {
- #if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
- char szRegName[MAX_DISPLAY_NAME] = {0}; /* Flawfinder: ignore */
- m_pStats = new PLAYER_STATS(m_pRegistry, unRegistryID);
- m_pRegistry->AddInt("Statistics.StreamSwitchOccured", 0);
- if (m_pRegistry &&
- HXR_OK == m_pRegistry->GetPropName(unRegistryID, pPlayerRegName))
- {
- SafeSprintf(szRegName, MAX_DISPLAY_NAME, "%s.Repeat", pPlayerRegName->GetBuffer());
- m_ulRepeatedRegistryID = m_pRegistry->AddComp(szRegName);
- SafeSprintf(szRegName, MAX_DISPLAY_NAME, "%s.NextGroup", pPlayerRegName->GetBuffer());
- m_ulNextGroupRegistryID = m_pRegistry->AddComp(szRegName);
- }
- HX_RELEASE(pPlayerRegName);
- #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
- #if defined(HELIX_FEATURE_REGISTRY) && defined(HELIX_FEATURE_MASTERTAC)
- // create master TAC object
- UINT32 playerID = 0;
- GetID(playerID);
- m_pMasterTAC->SetRegistry(m_pRegistry,playerID);
- #endif /* HELIX_FEATURE_REGISTRY && HELIX_FEATURE_MASTERTAC*/
- }
- m_pCookies = m_pEngine->GetCookies();
- }
- else
- {
- theErr = HXR_INVALID_PARAMETER;
- }
- if (m_pAudioPlayer && theErr == HXR_OK)
- {
- m_pAudioPlayer->AddRef();
- theErr = m_pAudioPlayer->Init((IUnknown*) (IHXPlayer*)this);
- }
- #if defined(HELIX_FEATURE_NEXTGROUPMGR)
- if (m_pNextGroupManager)
- {
- m_pNextGroupManager->Init();
- }
- #endif /* HELIX_FEATURE_NEXTGROUPMGR */
- return theErr;
- }
- /************************************************************************
- * Method:
- * IHXPlayer::IsDone
- * Purpose:
- * Ask the player if it is done with the current presentation
- *
- */
- STDMETHODIMP_ (BOOL) HXPlayer::IsDone(void)
- {
- return m_bIsPresentationDone;
- }
- /************************************************************************
- * Method:
- * IHXPlayer::IsLive
- * Purpose:
- * Ask the player whether it contains the live source
- *
- */
- STDMETHODIMP_ (BOOL) HXPlayer::IsLive(void)
- {
- return m_bIsLive;
- }
- /************************************************************************
- * Method:
- * IHXPlayer::GetCurrentPlayTime
- * Purpose:
- * Get the current time on the Player timeline
- *
- */
- STDMETHODIMP_ (ULONG32) HXPlayer::GetCurrentPlayTime(void)
- {
- HX_RESULT theErr = HXR_OK;
- m_bCoreLocked = TRUE;
- m_pCoreMutex->Lock();
- theErr = m_pAudioPlayer->GetCurrentPlayBackTime();
- m_pCoreMutex->Unlock();
- m_bCoreLocked = FALSE;
- return theErr;
- }
- /************************************************************************
- * Method:
- * IHXPlayer::AddAdviseSink
- * Purpose:
- * Call this method to add a client advise sink.
- *
- */
- STDMETHODIMP HXPlayer::AddAdviseSink (IHXClientAdviseSink* pAdviseSink)
- {
- #if defined(HELIX_FEATURE_SINKCONTROL)
- if (m_pAdviseSink)
- {
- return m_pAdviseSink->AddAdviseSink(pAdviseSink);
- }
- else
- #endif /* HELIX_FEATURE_SINKCONTROL */
- {
- return HXR_NOTIMPL;
- }
- }
- /************************************************************************
- * Method:
- * IHXPlayer::RemoveAdviseSink
- * Purpose:
- * Call this method to remove a client advise sink.
- */
- STDMETHODIMP HXPlayer::RemoveAdviseSink(IHXClientAdviseSink* pAdviseSink)
- {
- HX_RESULT theErr = HXR_OK;
- m_bCoreLocked = TRUE;
- m_pCoreMutex->Lock();
- #if defined(HELIX_FEATURE_SINKCONTROL)
- if (m_pAdviseSink)
- {
- theErr = m_pAdviseSink->RemoveAdviseSink(pAdviseSink);
- }
- #endif /* HELIX_FEATURE_SINKCONTROL */
- m_pCoreMutex->Unlock();
- m_bCoreLocked = FALSE;
- return theErr;
- }
- ULONG32 HXPlayer::GetInst(void)
- {
- #if defined(_WIN32)
- return (ULONG32)GetModuleHandle(NULL);
- #elif defined(_WIN16)
- return (ULONG32)g_hInstance;
- #else
- return 0;
- #endif
- }
- HX_RESULT
- HXPlayer::SetStatsGranularity
- (
- ULONG32 ulGranularity
- )
- {
- #if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
- m_ulStatsGranularity = ulGranularity;
- if (m_pUpdateStatsCallback->m_bIsCallbackPending && ALLFS == m_ulStatsGranularity)
- {
- m_pUpdateStatsCallback->m_bIsCallbackPending = FALSE;
- m_pScheduler->Remove(m_pUpdateStatsCallback->m_PendingHandle);
- m_pUpdateStatsCallback->m_PendingHandle = 0;
- }
- else if (!m_pUpdateStatsCallback->m_bIsCallbackPending && ALLFS != m_ulStatsGranularity)
- {
- UpdateStatistics();
- }
- return HXR_OK;
- #else
- return HXR_NOTIMPL;
- #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
- }
- STDMETHODIMP
- HXPlayer::ClosePresentation()
- {
- m_bCoreLocked = TRUE;
- m_pCoreMutex->Lock();
- // This stops the player if it is playing and cleans up the layout.
- StopPlayer(END_STOP);
- CloseAllRenderers(0);
- #if defined(HELIX_FEATURE_VIDEO)
- if (m_pSiteSupplier && !m_bBeginChangeLayoutTobeCalled)
- {
- m_bBeginChangeLayoutTobeCalled = TRUE;
- m_pSiteSupplier->DoneChangeLayout();
- }
- #endif /* HELIX_FEATURE_VIDEO */
- m_pCoreMutex->Unlock();
- m_bCoreLocked = FALSE;
- return HXR_OK;
- }
- STDMETHODIMP
- HXPlayer::SetMinimumPreroll(UINT32 ulMinPreroll)
- {
- HX_RESULT hr = HXR_OK;
- m_ulMinimumTotalPreroll = ulMinPreroll;
- return hr;
- }
- STDMETHODIMP
- HXPlayer::GetMinimumPreroll(REF(UINT32) ulMinPreroll)
- {
- HX_RESULT hr = HXR_OK;
- ulMinPreroll = m_ulMinimumTotalPreroll;
- return hr;
- }
- HX_RESULT
- HXPlayer::UpdateStatistics(void)
- {
- #if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
- BOOL bUpdate = FALSE;
- ULONG32 ulPlayerTotal = 0;
- ULONG32 ulPlayerReceived = 0;
- ULONG32 ulPlayerNormal = 0;
- ULONG32 ulPlayerRecovered = 0;
- ULONG32 ulPlayerDuplicate = 0;
- ULONG32 ulPlayerOutOfOrder = 0;
- ULONG32 ulPlayerLost = 0;
- ULONG32 ulPlayerLate = 0;
- UINT32 ulPlayerTotal30 = 0;
- UINT32 ulPlayerLost30 = 0;
- ULONG32 ulPlayerResendRequested = 0;
- ULONG32 ulPlayerResendReceived = 0;
- ULONG32 ulPlayerBandwidth = 0;
- ULONG32 ulPlayerCurBandwidth = 0;
- ULONG32 ulPlayerAvgBandwidth = 0;
- INT32 lAvgLatency = 0;
- INT32 lHighLatency = 0;
- INT32 lLowLatency = 0xFFFF;
- ULONG32 ulStreamNumber = 0;
- SourceInfo* pSourceInfo = NULL;
- RendererInfo* pRenderInfo = NULL;
- IHXStatistics* pStatistics = NULL;
- UINT16 uBufferingMode = 0;
- CHXMapPtrToPtr::Iterator ndxSource;
- CHXMapLongToObj::Iterator ndxRend;
- if (!m_bInitialized || m_bPaused)
- {
- goto exit;
- }
- // update statistics
- ndxSource = m_pSourceMap->Begin();
- for (; ndxSource != m_pSourceMap->End(); ++ndxSource)
- {
- pSourceInfo = (SourceInfo*) (*ndxSource);
- // notify the renderer to update its statistics
- ndxRend = pSourceInfo->m_pRendererMap->Begin();
- for (; ndxRend != pSourceInfo->m_pRendererMap->End(); ++ndxRend)
- {
- pRenderInfo = (RendererInfo*)(*ndxRend);
- if (pRenderInfo->m_pRenderer &&
- HXR_OK == pRenderInfo->m_pRenderer->
- QueryInterface(IID_IHXStatistics,
- (void**)&pStatistics))
- {
- pStatistics->UpdateStatistics();
- pStatistics->Release();
- pStatistics = NULL;
- }
- }
- // update each source
- if (pSourceInfo->m_pSource &&
- HXR_OK == pSourceInfo->m_pSource->UpdateStatistics())
- {
- ulPlayerTotal += pSourceInfo->m_pSource->m_pStats->m_pTotal->GetInt();
- ulPlayerReceived += pSourceInfo->m_pSource->m_pStats->m_pReceived->GetInt();
- ulPlayerNormal += pSourceInfo->m_pSource->m_pStats->m_pNormal->GetInt();
- ulPlayerRecovered += pSourceInfo->m_pSource->m_pStats->m_pRecovered->GetInt();
- ulPlayerDuplicate += pSourceInfo->m_pSource->m_pStats->m_pDuplicate->GetInt();
- ulPlayerOutOfOrder += pSourceInfo->m_pSource->m_pStats->m_pOutOfOrder->GetInt();
- ulPlayerLost += pSourceInfo->m_pSource->m_pStats->m_pLost->GetInt();
- ulPlayerLate += pSourceInfo->m_pSource->m_pStats->m_pLate->GetInt();
- ulPlayerResendRequested += pSourceInfo->m_pSource->m_pStats->m_pResendRequested->GetInt();
- ulPlayerResendReceived += pSourceInfo->m_pSource->m_pStats->m_pResendReceived->GetInt();
- ulPlayerTotal30 += pSourceInfo->m_pSource->m_pStats->m_pTotal30->GetInt();
- ulPlayerLost30 += pSourceInfo->m_pSource->m_pStats->m_pLost30->GetInt();
- ulPlayerBandwidth += pSourceInfo->m_pSource->m_pStats->m_pClipBandwidth->GetInt();
- ulPlayerCurBandwidth += pSourceInfo->m_pSource->m_pStats->m_pCurBandwidth->GetInt();
- ulPlayerAvgBandwidth += pSourceInfo->m_pSource->m_pStats->m_pAvgBandwidth->GetInt();
- lAvgLatency += pSourceInfo->m_pSource->m_pStats->m_pAvgLatency->GetInt();
- if (lHighLatency < pSourceInfo->m_pSource->m_pStats->m_pHighLatency->GetInt())
- {
- lHighLatency = pSourceInfo->m_pSource->m_pStats->m_pHighLatency->GetInt();
- }
- if (lLowLatency > pSourceInfo->m_pSource->m_pStats->m_pLowLatency->GetInt())
- {
- lLowLatency = pSourceInfo->m_pSource->m_pStats->m_pLowLatency->GetInt();
- }
- if (uBufferingMode < (UINT16) pSourceInfo->m_pSource->m_pStats->m_pBufferingMode->GetInt())
- {
- uBufferingMode = (UINT16) pSourceInfo->m_pSource->m_pStats->m_pBufferingMode->GetInt();
- }
- if (pSourceInfo->m_pSource->m_pStatsManager)
- {
- pSourceInfo->m_pSource->m_pStatsManager->Copy();
- }
- }
- }
- bUpdate = SetIntIfNecessary(m_pStats->m_pTotal, (INT32)ulPlayerTotal);
- bUpdate |= SetIntIfNecessary(m_pStats->m_pReceived, (INT32)ulPlayerReceived);
- bUpdate |= SetIntIfNecessary(m_pStats->m_pNormal, (INT32)ulPlayerNormal);
- bUpdate |= SetIntIfNecessary(m_pStats->m_pRecovered, (INT32)ulPlayerRecovered);
- bUpdate |= SetIntIfNecessary(m_pStats->m_pDuplicate, (INT32)ulPlayerDuplicate);
- bUpdate |= SetIntIfNecessary(m_pStats->m_pOutOfOrder, (INT32)ulPlayerOutOfOrder);
- bUpdate |= SetIntIfNecessary(m_pStats->m_pLost, (INT32)ulPlayerLost);
- bUpdate |= SetIntIfNecessary(m_pStats->m_pLate, (INT32)ulPlayerLate);
- bUpdate |= SetIntIfNecessary(m_pStats->m_pTotal30, (INT32)ulPlayerTotal30);
- bUpdate |= SetIntIfNecessary(m_pStats->m_pLost30, (INT32)ulPlayerLost30);
- bUpdate |= SetIntIfNecessary(m_pStats->m_pResendRequested, (INT32)ulPlayerResendRequested);
- bUpdate |= SetIntIfNecessary(m_pStats->m_pResendReceived, (INT32)ulPlayerResendReceived);
- bUpdate |= SetIntIfNecessary(m_pStats->m_pClipBandwidth, (INT32)ulPlayerBandwidth);
- bUpdate |= SetIntIfNecessary(m_pStats->m_pCurBandwidth, (INT32)ulPlayerCurBandwidth);
- bUpdate |= SetIntIfNecessary(m_pStats->m_pAvgBandwidth, (INT32)ulPlayerAvgBandwidth);
- bUpdate |= SetIntIfNecessary(m_pStats->m_pAvgLatency, (INT32)lAvgLatency);
- bUpdate |= SetIntIfNecessary(m_pStats->m_pHighLatency, (INT32)lHighLatency);
- bUpdate |= SetIntIfNecessary(m_pStats->m_pLowLatency, (INT32)lLowLatency);
- bUpdate |= SetIntIfNecessary(m_pStats->m_pBufferingMode, (INT32)uBufferingMode);
- if (bUpdate || m_bForceStatsUpdate)
- {
- if (m_pAdviseSink)
- {
- m_pAdviseSink->OnStatisticsChanged();
- }
- m_bForceStatsUpdate = FALSE;
- }
- exit:
- if (!m_pUpdateStatsCallback->m_bIsCallbackPending && ALLFS != m_ulStatsGranularity)
- {
- m_pUpdateStatsCallback->m_bIsCallbackPending = TRUE;
- m_pUpdateStatsCallback->m_PendingHandle = m_pScheduler->RelativeEnter(m_pUpdateStatsCallback,
- m_ulStatsGranularity);
- }
- #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
- return HXR_OK;
- }
- HX_RESULT
- HXPlayer::SetupAudioPlayer()
- {
- HX_RESULT theErr = HXR_OK;
- HX_ASSERT(m_bInitialized);
- #if defined(THREADS_SUPPORTED) && !defined(_MAC_UNIX)
- if (m_bUseCoreThread && !m_pEngine->AtInterruptTime())
- {
- HX_ASSERT(m_pSetupCallback->GetPendingCallback() == 0);
- if (!m_pSetupCallback->GetPendingCallback())
- {
- m_pSetupCallback->CallbackScheduled(
- m_pScheduler->RelativeEnter(m_pSetupCallback, 0));
- }
- return HXR_OK;
- }
- #endif /*_WIN32*/
- m_bSetupToBeDone = FALSE;
- PrepareAudioPlayer();
- #if defined(THREADS_SUPPORTED) && !defined(_MAC_UNIX)
- if (m_bUseCoreThread && m_pEngine->AtInterruptTime())
- {
- m_pAudioPlayer->UseCoreThread();
- }
- #endif
- theErr = m_pAudioPlayer->Setup(m_ulLowestGranularity);
- if (theErr)
- {
- SetLastError(theErr);
- }
- if (!theErr)
- {
- m_bPostSetupToBeDone = TRUE;
- }
- return theErr;
- }
- HX_RESULT
- HXPlayer::PrepareAudioPlayer()
- {
- return HXR_OK;
- }
- HX_RESULT HXPlayer::ProcessIdle(void)
- {
- if ((!m_bInitialized || m_bPostSetupToBeDone ) && m_pEngine->AtInterruptTime())
- {
- return HXR_OK;
- }
- if (m_bCoreLocked)
- {
- SchedulePlayer();
- return HXR_OK;
- }
- m_pCoreMutex->Lock();
- #if 0
- #if defined(_WIN32) && defined(_DEBUG)
- GetChangesToWorkingSet();
- #endif
- #endif
- m_bCoreLocked = TRUE;
- HX_RESULT theErr = HXR_OK;
- BOOL bIsBuffering = FALSE;
- UINT16 uLowestBuffering = 100;
- SourceInfo* pSourceInfo = NULL;
- RendererInfo* pRendInfo = NULL;
- IHXRenderer* pRenderer = NULL;
- BOOL bDone = FALSE;
- BOOL bIsFirst = TRUE;
- BOOL bReadyToUpgrade = TRUE;
- BOOL bSuppressErrorReporting = FALSE;
- UINT32 ulNumStreamsToBeFilled = 0;
- UINT32 ulLoopEntryTime = 0;
- UINT16 unStatusCode = 0;
- UINT16 unPercentDone = 0;
- IHXBuffer* pStatusDesc = NULL;
- CHXMapPtrToPtr::Iterator ndxSource;
- CHXMapLongToObj::Iterator ndxRend;
- if (m_bIsDone || m_bSetupToBeDone)
- {
- goto exitRoutine;
- }
- #ifdef _MACINTOSH
- /* check InternalPause() for details */
- if (m_bPendingAudioPause && !m_pEngine->AtInterruptTime())
- {
- m_pAudioPlayer->Pause();
- }
- #endif
- ndxSource = m_pSourceMap->Begin();
- for (;!theErr && ndxSource != m_pSourceMap->End(); ++ndxSource)
- {
- pSourceInfo = (SourceInfo*)(*ndxSource);
- /* Do not call Process source at interrupt time unless
- * it is initialized.
- */
- if (pSourceInfo->m_pSource &&
- (pSourceInfo->m_pSource->IsInitialized() ||
- !m_pEngine->AtInterruptTime()))
- {
- // XXX HP may need to rework
- if (!pSourceInfo->m_bDone)
- {
- theErr = pSourceInfo->m_pSource->ProcessIdle();
- if( theErr == HXR_OUTOFMEMORY )
- {
- goto exitRoutine;
- }
- }
- theErr = SpawnSourceIfNeeded(pSourceInfo);
- if( theErr == HXR_OUTOFMEMORY )
- {
- goto exitRoutine;
- }
- else
- {
- theErr = HXR_OK; // filter out HXR_NOTIMPL
- }
- }
- if (pSourceInfo->m_pPeerSourceInfo &&
- pSourceInfo->m_pPeerSourceInfo->m_pSource &&
- !pSourceInfo->m_pPeerSourceInfo->m_bDone &&
- (pSourceInfo->m_pPeerSourceInfo->m_pSource->IsInitialized() ||
- !m_pEngine->AtInterruptTime()))
- {
- theErr = pSourceInfo->m_pPeerSourceInfo->m_pSource->ProcessIdle();
- if( theErr == HXR_OUTOFMEMORY )
- {
- goto exitRoutine;
- }
- }
- }
- #if defined(HELIX_FEATURE_PREFETCH)
- if (m_pPrefetchManager &&
- m_pPrefetchManager->GetNumSources() > 0)
- {
- m_pPrefetchManager->ProcessIdle();
- }
- #endif /* HELIX_FEATURE_PREFETCH */
- #if defined(HELIX_FEATURE_NEXTGROUPMGR)
- if (m_pNextGroupManager->GetNumSources() > 0)
- {
- m_pNextGroupManager->ProcessIdle();
- }
- #endif /* HELIX_FEATURE_NEXTGROUPMGR */
- // check the status first
- if (!m_bContactingDone &&
- HXR_OK == GetStatus(unStatusCode, pStatusDesc, unPercentDone))
- {
- if (HX_STATUS_CONTACTING == unStatusCode && pStatusDesc && m_pAdviseSink)
- {
- m_pAdviseSink->OnContacting((const char*)pStatusDesc->GetBuffer());
- }
- else if (HX_STATUS_INITIALIZING != unStatusCode)
- {
- m_bContactingDone = TRUE;
- }
- HX_RELEASE(pStatusDesc);
- }
- // initialize renderes if not done yet..
- // this involves reading headers from source object
- // creating the right renderers for each stream and pass this
- // header to the renderer.
- if (!m_bInitialized)
- {
- /* A temporary hack till we change SMIL fileformat
- * to send Layout info in Header
- */
- BOOL bIsSmilRenderer = m_bSetupLayoutSiteGroup;
- theErr = InitializeRenderers();
- #if defined(HELIX_FEATURE_VIDEO)
- if (!theErr && m_bInitialized && !m_bPlayerWithoutSources)
- {
- SetupLayout(/*!m_bSetupLayoutSiteGroup*/ FALSE);
- if (bIsSmilRenderer == m_bSetupLayoutSiteGroup &&
- m_pSiteSupplier && !m_bBeginChangeLayoutTobeCalled)
- {
- m_bBeginChangeLayoutTobeCalled = TRUE;
- m_pSiteSupplier->DoneChangeLayout();
- }
- }
- #endif /* HELIX_FEATURE_VIDEO */
- if (!theErr && m_bInitialized)
- {
- AdjustPresentationTime();
- m_bSetupToBeDone = TRUE;
- theErr = SetupAudioPlayer();
- }
- }
- if (m_bPostSetupToBeDone)
- {
- m_bPostSetupToBeDone = FALSE;
- /* Initialize audio services */
- if (!theErr && m_bInitialized)
- {
- m_bIsPresentationClosedToBeSent = TRUE;
- if (m_pAdviseSink)
- {
- m_pAdviseSink->OnPresentationOpened();
- }
- }
- if (!theErr && m_bInitialized)
- {
- m_ulMinimumAudioPreroll = m_pAudioPlayer->GetInitialPushdown();
- SetMinimumPushdown();
- }
- if (!theErr && m_bInitialized && !m_bIsFirstBegin)
- {
- CheckSourceRegistration();
- ndxSource = m_pSourceMap->Begin();
- for (; !theErr && ndxSource != m_pSourceMap->End(); ++ndxSource)
- {
- SourceInfo* pSourceInfo = (SourceInfo*) (*ndxSource);
- HXSource* pSource = pSourceInfo->m_pSource;
-
- if (pSource)
- {
- theErr = pSource->DoResume();
- }
- else
- {
- /* pSource should never be NULL */
- HX_ASSERT(FALSE);
- }
- }
- }
- /* Start Downloading even if we have not been issued a
- * Begin() command
- */
- if (!theErr && m_bInitialized && m_bIsFirstBegin && !m_bIsDone)
- {
- theErr = StartDownload();
- }
- }
- // if it is still not initialized check error code and return
- if (theErr || !m_bInitialized)
- {
- // my first use of goto..!!
- goto exitRoutine;
- }
- /* try to fill up packets from the various source objects for
- * different streams so that all of them are upto their preroll
- * mark...
- */
- UpdateCurrentPlayTime( m_pAudioPlayer->GetCurrentPlayBackTime() );
- if (!m_ToBeginRendererList.IsEmpty())
- {
- CheckBeginList();
- }
- while (!theErr && !bDone && m_uNumSourcesActive > 0)
- {
- ndxSource = m_pSourceMap->Begin();
- for (;!theErr && ndxSource != m_pSourceMap->End(); ++ndxSource)
- {
- pSourceInfo = (SourceInfo*)(*ndxSource);
- theErr = pSourceInfo->ProcessIdle(bIsFirst, ulNumStreamsToBeFilled,
- bIsBuffering, uLowestBuffering);
- if (pSourceInfo->m_pPeerSourceInfo)
- {
- BOOL tmp_bIsFirst = TRUE;
- BOOL tmp_bIsBuffering = FALSE;
- UINT32 tmp_ulNumStreamsToBeFilled = 0;
- UINT16 tmp_uLowestBuffering = 100;
- pSourceInfo->m_pPeerSourceInfo->ProcessIdle(tmp_bIsFirst, tmp_ulNumStreamsToBeFilled,
- tmp_bIsBuffering, tmp_uLowestBuffering);
- }
- /* Someone added a source during ProcessIdle.
- * Start all over again
- */
- if (m_bSourceMapUpdated)
- {
- break;
- }
- }
- if (bIsBuffering && !m_bIsPlaying)
- {
- if (!ulLoopEntryTime)
- {
- ulLoopEntryTime = HX_GET_TICKCOUNT();
- }
- ndxSource = m_pSourceMap->Begin();
- for (;!theErr && ndxSource != m_pSourceMap->End(); ++ndxSource)
- {
- pSourceInfo = (SourceInfo*)(*ndxSource);
- ndxRend = pSourceInfo->m_pRendererMap->Begin();
- for (;!theErr && ndxRend != pSourceInfo->m_pRendererMap->End();
- ++ndxRend)
- {
- pRendInfo = (RendererInfo*)(*ndxRend);
- pRenderer = pRendInfo->m_pRenderer;
- if((pRendInfo->m_bInterruptSafe || !m_pEngine->AtInterruptTime())
- && pRenderer)
- {
- pRenderer->OnBuffering(m_BufferingReason, uLowestBuffering);
- }
- }
- }
- m_b100BufferingToBeSent = TRUE;
- if (m_pAdviseSink)
- {
- m_pAdviseSink->OnBuffering(m_BufferingReason, uLowestBuffering);
- }
- // free some CPU time if we stuck in this WHILE loop too long
- if (!theErr &&
- CALCULATE_ELAPSED_TICKS(ulLoopEntryTime, HX_GET_TICKCOUNT()) >= MAX_LOOP_EXE_TIME)
- {
- break;
- }
- if (!theErr)
- {
- theErr = ProcessCurrentEvents();
- }
- }
- if (theErr || m_bSourceMapUpdated)
- {
- m_bSourceMapUpdated = FALSE;
- goto exitRoutine;
- }
- bIsFirst = FALSE;
- if (ulNumStreamsToBeFilled == 0)
- {
- bDone = TRUE;
- }
- }
- // SPECIAL CASE:
- // the player received all the packets(m_uNumSourcesActive is 0) and
- // EndOfPacket() hasn't been sent to the renderer yet,
- // BUT the renderer still calls ReportRebufferStatus()
- // we need to make sure the rebuffering is done before calling resume.
- if (m_uNumSourcesActive == 0)
- {
- ndxSource = m_pSourceMap->Begin();
- for (;!theErr && ndxSource != m_pSourceMap->End(); ++ndxSource)
- {
- pSourceInfo = (SourceInfo*)(*ndxSource);
- if (!pSourceInfo->IsRebufferDone())
- {
- bIsBuffering = TRUE;
- break;
- }
- }
- }
- /* Stop Downloading if we have not been issued a
- * Begin() command and we are done with Buffering.
- */
- if (!theErr && !bIsBuffering && m_bFastStartInProgress && !m_bIsDone)
- {
- theErr = PauseDownload();
- }
- // Process Current Events Due...
- if (!theErr)
- {
- theErr = ProcessCurrentEvents();
- }
- // repeat source specific
- SwitchSourceIfNeeded();
- if (!theErr && !bIsBuffering &&
- (!m_bResumeOnlyAtSystemTime || !m_pEngine->AtInterruptTime()))
- {
- theErr = CheckForAudioResume();
- }
- if (!theErr && !m_bLastGroup && !m_bNextGroupStarted && !m_pEngine->AtInterruptTime())
- {
- CheckToStartNextGroup();
- }
- /* Check if live stream has ended */
- if (!theErr && m_bInitialized && !m_bPlayerWithoutSources &&
- ((!m_bIsLive && (!m_ulPresentationDuration ||
- (m_ulPresentationDuration < m_ulCurrentPlayTime))) ||
- (m_bIsLive && AreAllPacketsSent())) &&
- m_uNumSourcesActive == 0)
- {
- /* If there are any sources that MUST be initialized before playback
- * begins/stops, we should not end the presentation here. Instead, wait for
- * the stream headers to come down...
- */
- if ((m_uNumSourceToBeInitializedBeforeBegin > 0) &&
- m_ulPresentationDuration)
- {
- InternalPause();
- }
- else if (!m_ulPresentationDuration ||
- (m_ulPresentationDuration < m_ulCurrentPlayTime))
- {
- if (ScheduleOnTimeSync())
- {
- // schedule a system callback to ensure
- // the renderers receive OnTimeSync() on its duration
- // AND the clip ends ASAP
- RemovePendingCallback(m_pHXPlayerCallback);
- m_pHXPlayerCallback->CallbackScheduled(
- m_pScheduler->RelativeEnter(m_pHXPlayerCallback, 0));
- goto cleanup;
- }
- else
- {
- m_bIsDone = TRUE;
- m_pAudioPlayer->DonePlayback();
- /* This assert is to find bugs in fileformats which place invalid ts
- * (ts > m_ulPresentationDuration) on the packets.
- */
- HX_ASSERT(AreAllPacketsSent() == TRUE);
- }
- }
- }
- exitRoutine:
- #if defined(HELIX_FEATURE_AUTOUPGRADE)
- if(m_pUpgradeCollection && m_pUpgradeCollection->GetCount() > 0 && !m_pEngine->AtInterruptTime())
- {
- // Request an upgrade
- IHXUpgradeHandler* pUpgradeHandler = NULL;
- if(m_pClient)
- m_pClient->QueryInterface(IID_IHXUpgradeHandler, (void**)&pUpgradeHandler);
- if(!pUpgradeHandler)
- {
- // In case of clients with no IHXUpgradeHandler support
- // just remove all the upgrade collectopn components
- m_pUpgradeCollection->RemoveAll();
- theErr = HXR_MISSING_COMPONENTS;
- }
- else
- {
- // see if we should send an upgrade request only if all the sources
- // have been initialized...
- ndxSource = m_pSourceMap->Begin();
- for (;ndxSource != m_pSourceMap->End(); ++ndxSource)
- {
- pSourceInfo = (SourceInfo*)(*ndxSource);
- if (!pSourceInfo->m_bLoadPluginAttempted &&
- pSourceInfo->m_pSource &&
- pSourceInfo->m_pSource->GetLastError() == HXR_OK)
- {
- bReadyToUpgrade = FALSE;
- break;
- }
- }
- if (bReadyToUpgrade)
- {
- // Request an upgrade
- IHXUpgradeHandler* pUpgradeHandler = NULL;
- if(m_pClient)
- m_pClient->QueryInterface(IID_IHXUpgradeHandler, (void**)&pUpgradeHandler);
- if(pUpgradeHandler)
- {
- HX_RESULT hr = HXR_MISSING_COMPONENTS;
- m_bIsPresentationClosedToBeSent = TRUE;
- HX_RESULT nUpgradeResult = pUpgradeHandler->RequestUpgrade(m_pUpgradeCollection, FALSE);
- if(nUpgradeResult == HXR_OK || nUpgradeResult == HXR_CANCELLED)
- {
- // We want to stop playback but we dont want error
- // to be reported untill upgrade tries to fix situation.
- hr = HXR_OK;
- bSuppressErrorReporting = TRUE;
- }
- m_bIsDone = TRUE;
- m_pAudioPlayer->DonePlayback();
- m_LastError = hr;
- }
- HX_RELEASE(pUpgradeHandler);
- m_pUpgradeCollection->RemoveAll();
- }
- else
- {
- /* We are not done yet... Wait till all the sources have been
- * attempted to load required plugins
- */
- m_bIsDone = FALSE;
- }
- }
- }
- #endif /* HELIX_FEATURE_AUTOUPGRADE */
- if (!theErr && m_pAltURLs && m_pAltURLs->GetCount() && !m_pEngine->AtInterruptTime())
- {
- theErr = DoAltURL();
- }
- if (!theErr && m_pRedirectList && m_pRedirectList->GetCount() && !m_pEngine->AtInterruptTime())
- {
- theErr = DoRedirect();
- }
- if (!theErr && m_bIsDone && !m_bTimeSyncLocked && !m_pEngine->AtInterruptTime())
- {
- if (m_LastError != HXR_OK)
- {
- m_bIsDone = FALSE;
- PausePlayer(FALSE);
- m_bIsDone = TRUE;
- ActualReport(m_LastSeverity, m_LastError,
- m_ulLastUserCode, m_pLastUserString, m_pLastMoreInfoURL);
- ResetError();
- }
- PlayNextGroup();
- }
- if (!theErr)
- {
- ProcessIdleExt();
- }
- SchedulePlayer();
- /* this error is crucial...need to be reported upto ragui...*/
- if (theErr && !bSuppressErrorReporting)
- {
- SetLastError(theErr);
- }
- cleanup:
- m_bCoreLocked = FALSE;
- m_pCoreMutex->Unlock();
- return theErr;
- }
- HX_RESULT
- HXPlayer::ProcessIdleExt(void)
- {
- return HXR_OK;
- }
- HX_RESULT
- HXPlayer::DoAltURL(void)
- {
- #if defined(HELIX_FEATURE_ALT_URL)
- HX_RESULT hr = HXR_OK;
- BOOL bDefault = FALSE;
- char* pAltURL = NULL;
- SourceInfo* pMainSourceInfo = NULL;
- HXSource* pSource = NULL;
- ResetError();
- while (!hr && m_pAltURLs->GetCount())
- {
- pMainSourceInfo = (SourceInfo*) m_pAltURLs->RemoveHead();
- #if defined(HELIX_FEATURE_NEXTGROUPMGR)
- if (pMainSourceInfo->m_pSource->IsPartOfNextGroup())
- {
- m_pNextGroupManager->RemoveSource(pMainSourceInfo);
- m_bPartOfNextGroup = TRUE;
- }
- else
- #endif /* HELIX_FEATURE_NEXTGROUPMGR */
- #if defined(HELIX_FEATURE_PREFETCH)
- if (pMainSourceInfo->m_pSource->IsPartOfPrefetchGroup())
- {
- m_pPrefetchManager->RemoveSource(pMainSourceInfo);
- }
- else
- #endif /* HELIX_FEATURE_PREFETCH */
- {
- m_pSourceMap->RemoveKey(pMainSourceInfo->m_pSource);
- m_bSourceMapUpdated = TRUE;
- }
- if (pMainSourceInfo->m_bTobeInitializedBeforeBegin &&
- m_uNumSourceToBeInitializedBeforeBegin > 0)
- {
- m_uNumSourceToBeInitializedBeforeBegin--;
- }
- pAltURL = pMainSourceInfo->m_pSource->GetAltURL(bDefault);
- HX_ASSERT(pAltURL);
- pMainSourceInfo->Stop();
- #if defined(HELIX_FEATURE_NESTEDMETA)
- HXPersistentComponent* pRootPersistentComponent = m_pPersistentComponentManager->m_pRootPersistentComponent;
- // only cleanup the layout if
- // * it's not a SMIL presentation OR
- // * the AltURL is on the root SMIL presentation itself
- // in other words
- // * don't cleanup the layout if the AltURL is on the tracks
- // * within the SMIL presentation
- UINT32 ulPCID = pMainSourceInfo->m_ulPersistentComponentID;
- HXPersistentComponent* pPersistentComponent = NULL;
- PersistentType SourceType = PersistentUnknown;
-
- m_pPersistentComponentManager->GetPersistentComponent(ulPCID,
- (IHXPersistentComponent*&)pPersistentComponent
- );
- if( pPersistentComponent )
- SourceType = (PersistentType)pPersistentComponent->m_ulPersistentType;
-
- HX_RELEASE(pPersistentComponent);
-
- if( !pRootPersistentComponent ||
- SourceType != PersistentSMIL ||
- pRootPersistentComponent->m_pSourceInfo == pMainSourceInfo)
- {
- CleanupLayout();
- if (pRootPersistentComponent)
- {
- pRootPersistentComponent->m_bCleanupLayoutCalled = TRUE;
- }
- }
- #endif /* HELIX_FEATURE_NESTEDMETA */
- pMainSourceInfo->CloseRenderers();
- if (pAltURL)
- {
- hr = DoAltURLOpen(pAltURL, bDefault, pMainSourceInfo);
- }
- m_bPartOfNextGroup = FALSE;
- HX_VECTOR_DELETE(pAltURL);
- HX_DELETE(pMainSourceInfo);
- }
- return hr;
- #else
- return HXR_NOTIMPL;
- #endif /* HELIX_FEATURE_ALT_URL */
- }
- HX_RESULT
- HXPlayer::DoRedirect(void)
- {
- HX_RESULT hr = HXR_OK;
- BOOL bNoRedirectSupport = FALSE;
- BOOL bBegin = m_bUserHasCalledBegin;
- BOOL bRAMOnly = TRUE;
- SourceInfo* pSourceInfo = NULL;
- RedirectInfo* pRedirectInfo = NULL;
- IHXValues* pRequestHeaders = NULL;
- HXPersistentComponent* pRootPersistentComponent = NULL;
- HXPersistentComponent* pPersistentComponent = NULL;
- m_bDoRedirect = TRUE;
- pRedirectInfo = (RedirectInfo*) m_pRedirectList->RemoveHead();
- #if defined(HELIX_FEATURE_NESTEDMETA)
- pRootPersistentComponent = m_pPersistentComponentManager->m_pRootPersistentComponent;
- if (pRootPersistentComponent)
- {
- // no redirect support by default
- bNoRedirectSupport = TRUE;
- // except the live source within a RAM
- GetSourceInfo(pRedirectInfo->m_nGroupID, pRedirectInfo->m_nTrackID, pSourceInfo);
- if (pSourceInfo)
- {
- m_pPersistentComponentManager->GetPersistentComponent(pSourceInfo->m_ulPersistentComponentID,
- (IHXPersistentComponent*&)pPersistentComponent);
- // allow redirect on the root persistent component(i.e. SMIL/RAM)
- if (pPersistentComponent == pRootPersistentComponent)
- {
- bNoRedirectSupport = FALSE;
- }
- else
- {
- while (pPersistentComponent != pRootPersistentComponent)
- {
- if (PersistentSMIL == pPersistentComponent->m_ulPersistentType)
- {
- bRAMOnly = FALSE;
- break;
- }
- pPersistentComponent = pPersistentComponent->m_pPersistentParent;
- }
- if (pRootPersistentComponent->m_ulPersistentType == PersistentRAM &&
- bRAMOnly &&
- pSourceInfo->m_pSource &&
- pSourceInfo->m_pSource->IsLive())
- {
- bNoRedirectSupport = FALSE;
- }
- }
- HX_RELEASE(pPersistentComponent);
- }
- else
- {
- HX_ASSERT(FALSE);
- }
- }
- #endif /* HELIX_FEATURE_NESTEDMETA */
- // no Redirect support for SMIL presentation for now
- // return HXR_SERVER_DISCONNECTED instead
- if (bNoRedirectSupport)
- {
- Report(HXLOG_ERR, HXR_SERVER_DISCONNECTED, HXR_OK, NULL, NULL);
- goto cleanup;
- }
- if (m_pRequest)
- m_pRequest->GetRequestHeaders(pRequestHeaders);
- // Set the redirecting property to true before calling stop so the TLC can tell if a redirect is going to occur
- if (pRequestHeaders)
- pRequestHeaders->SetPropertyULONG32("IsRedirecting", TRUE);
- StopPlayer(END_REDIRECT);
- CloseAllRenderers(m_nCurrentGroup);
- // Set the redirecting property to false before opening the new URL.
- if (pRequestHeaders)
- {
- pRequestHeaders->SetPropertyULONG32("IsRedirecting", FALSE);
- HX_RELEASE(pRequestHeaders);
- }
- hr = OpenRedirect(pRedirectInfo->m_pURL);
- if (hr == HXR_OK && bBegin)
- {
- Begin();
- }
- cleanup:
- HX_DELETE(pRedirectInfo);
- m_bDoRedirect = FALSE;
- return hr;
- }
- HX_RESULT
- HXPlayer::OpenRedirect(const char* pszURL)
- {
- HX_RESULT hr = HXR_OK;
- // we want to protect against the TLC opening another URL
- if (m_bSetModal)
- {
- return HXR_OK;
- }
- HX_RELEASE(m_pRequest);
- // get the compresses URL
- CHXURL url(pszURL);
- m_pRequest = new CHXRequest();
- if( m_pRequest )
- {
- m_pRequest->AddRef();
- m_pRequest->SetURL(url.GetURL());
- m_bActiveRequest = TRUE;
- hr = DoURLOpen(&url, NULL);
- }
- else
- {
- hr = HXR_OUTOFMEMORY;
- }
- return hr;
- }
- HX_RESULT
- HXPlayer::StartDownload()
- {
- HX_RESULT theErr = HXR_OK;
- CHXMapPtrToPtr::Iterator ndxSource;
- if (!m_bIsDone)
- {
- CheckSourceRegistration();
- ndxSource = m_pSourceMap->Begin();
- /* Check if we are done. This may be TRUE for empty files */
- for (; !theErr && ndxSource != m_pSourceMap->End(); ++ndxSource)
- {
- SourceInfo* pSourceInfo = (SourceInfo*) (*ndxSource);
- HXSource* pSource = pSourceInfo->m_pSource;
-
- if(pSource && pSource->CanBeResumed())
- {
- theErr = pSource->StartInitialization();
- }
- }
- }
- m_bFastStartInProgress = TRUE;
- m_bFSBufferingEnd = FALSE;
- return theErr;
- }
- HX_RESULT
- HXPlayer::PauseDownload(void)
- {
- HX_RESULT theErr = HXR_OK;
- CHXMapPtrToPtr::Iterator ndxSource;
- if (!m_bFSBufferingEnd)
- {
- m_bFSBufferingEnd = TRUE;
- m_ulFSBufferingEndTime = HX_GET_TICKCOUNT();
- /* In network case, we want to buffer extra 2-3 seconds worth
- * of data. We renter this function over and over again in the
- * else clause and ultimately send 100% buffering message.
- * In local playback however, we want to send this message
- * right away. So do not return the function from here, instead fall
- * down below to return 100% buffering message instantly
- */
- if (!m_bAllLocalSources)
- {
- return HXR_OK;
- }
- }
- else
- {
- /* Buffer extra 3 seconds worth of data before pausing */
- if (CALCULATE_ELAPSED_TICKS(m_ulFSBufferingEndTime, HX_GET_TICKCOUNT())
- < 3000)
- {
- return HXR_OK;
- }
- }
- m_bFastStartInProgress = FALSE;
- ndxSource = m_pSourceMap->Begin();
- /* Check if we are done. This may be TRUE for empty files */
- for (; !theErr && !m_bIsDone && ndxSource != m_pSourceMap->End(); ++ndxSource)
- {
- SourceInfo* pSourceInfo = (SourceInfo*) (*ndxSource);
- HXSource* pSource = pSourceInfo->m_pSource;
- /* Do not pause a live source */
- if(!pSource || pSource->IsLive())
- {
- continue;
- }
- theErr = pSource->DoPause();
- }
- if (m_b100BufferingToBeSent)
- {
- m_b100BufferingToBeSent = FALSE;
- if (m_pAdviseSink)
- {
- m_pAdviseSink->OnBuffering(m_BufferingReason, 100);
- }
- }
- return theErr;
- }
- void
- HXPlayer::SchedulePlayer(void)
- {
- if ((!m_bIsDone || m_LastError || m_pEngine->AtInterruptTime()) &&
- !m_pHXPlayerCallback->GetPendingCallback())
- {
- m_pHXPlayerCallback->CallbackScheduled(
- m_pScheduler->RelativeEnter(m_pHXPlayerCallback, 300));
- }
- if ((!m_bIsDone || m_LastError) &&
- !m_pHXPlayerInterruptCallback->GetPendingCallback())
- {
- m_pHXPlayerInterruptCallback->CallbackScheduled(
- m_pScheduler->RelativeEnter(m_pHXPlayerInterruptCallback, 100));
- }
- }
- HX_RESULT
- HXPlayer::CheckForAudioResume(void)
- {
- HX_RESULT theErr = HXR_OK;
- if (m_bInitialized && !m_bSetupToBeDone && !m_bPaused &&
- (m_bBeginPending || m_bTimelineToBeResumed) &&
- m_uNumSourceToBeInitializedBeforeBegin == 0)
- {
- if (m_b100BufferingToBeSent)
- {
- m_b100BufferingToBeSent = FALSE;
- if (m_pAdviseSink)
- {
- m_pAdviseSink->OnBuffering(m_BufferingReason, 100);
- }
- }
- /*
- * change the state of buffering since we have crossed
- * initial startup state...
- * BUFFERING_SEEK and BUFFERING_LIVE_PAUSE are handled in OnTimeSync
- */
- if (m_BufferingReason == BUFFERING_START_UP)
- {
- m_BufferingReason = BUFFERING_CONGESTION;
- }
- /* did someone pause/stop the player within 100% OnBuffering call?
- * if so, do not resume the timeline yet.
- */
- if (m_bPaused || !m_bInitialized)
- {
- return HXR_OK;
- }
- m_bIsPlaying = TRUE;
- m_bBeginPending = FALSE;
- m_bTimelineToBeResumed = FALSE;
- m_bPendingAudioPause = FALSE;
- DEBUG_OUT(this, DOL_TRANSPORT, (s,"Audio Resumed"));
- theErr = m_pAudioPlayer->Resume();
- }
- return theErr;
- }
- void HXPlayer::SetMinimumPushdown()
- {
- UINT32 ulMinimumStartingPreroll = m_ulMinimumAudioPreroll;
- #ifndef HELIX_CONFIG_MIN_PCM_PUSHDOWN_BYTES
- // This is removed for HELIX_CONFIG_MIN_PCM_PUSHDOWN_BYTES
- // (MIN_HEAP) builds because this code will return a shorter
- // preroll value than is required for proper playback. This will cause
- // rebuffers with renderers that are driven by OnDryNotification()
- // because the core will not provide the renderer with packets early
- // enough. By removing this call the core will use the proper preroll
- // value and packets will be provided to the renderer in time to
- // satisfy all OnDryNotification() calls
- if (m_pAudioPlayer)
- {
- ulMinimumStartingPreroll = m_pAudioPlayer->GetInitialPushdown(TRUE);
- }
- #endif /* HELIX_CONFIG_MIN_PCM_PUSHDOWN_BYTES */
- CHXMapPtrToPtr::Iterator ndxSource = m_pSourceMap->Begin();
- for (; ndxSource != m_pSourceMap->End(); ++ndxSource)
- {
- SourceInfo* pSourceInfo = (SourceInfo*)(*ndxSource);
- HXSource* pSource = pSourceInfo->m_pSource;
- pSource->SetMinimumPreroll(m_ulMinimumAudioPreroll, ulMinimumStartingPreroll);
- }
- }
- void
- HXPlayer::ResetError(void)
- {
- m_LastSeverity = HXLOG_ERR;
- m_LastError = HXR_OK;
- m_ulLastUserCode = HXR_OK;
- HX_VECTOR_DELETE(m_pLastUserString);
- HX_VECTOR_DELETE(m_pLastMoreInfoURL);
- }
- void
- HXPlayer::SetLastError(HX_RESULT theErr)
- {
- if (theErr && !m_LastError)
- {
- m_LastError = theErr;
- m_bIsDone = TRUE;
- m_pAudioPlayer->DonePlayback();
- }
- // Handle OOM errors as special case: we do not want to continue playback
- // any longer.
- // Add SLOW_MACHINE to the "Abort Now" category.
- if( theErr == HXR_OUTOFMEMORY || theErr == HXR_SLOW_MACHINE )
- {
- // ActualReport does not get called next time in ProcessIdle because
- // we Abort playback here, so have to call it manually.
- ActualReport(m_LastSeverity, m_LastError,
- m_ulLastUserCode, m_pLastUserString, m_pLastMoreInfoURL);
- AbortPlayer();
- }
- }
- void
- HXPlayer::ResetRedirectList(void)
- {
- RedirectInfo* pRedirectInfo = NULL;
- if (m_pRedirectList)
- {
- CHXSimpleList::Iterator i = m_pRedirectList->Begin();
- for (; i != m_pRedirectList->End(); ++i)
- {
- pRedirectInfo = (RedirectInfo*) (*i);
- HX_DELETE(pRedirectInfo);
- }
- m_pRedirectList->RemoveAll();
- }
- }
- HX_RESULT
- HXPlayer::HandleRedirectRequest(UINT16 nGroup, UINT16 nTrack, char* pURL)
- {
- HX_RESULT theErr = HXR_OK;
- RedirectInfo* pRedirectInfo = NULL;
- if (!m_pRedirectList)
- {
- m_pRedirectList = new CHXSimpleList();
- if (!m_pRedirectList)
- {
- theErr = HXR_OUTOFMEMORY;
- goto cleanup;
- }
- }
- pRedirectInfo = new RedirectInfo;
- pRedirectInfo->m_pURL = new char[strlen(pURL)+1];
- strcpy(pRedirectInfo->m_pURL, pURL); /* Flawfinder: ignore */
- pRedirectInfo->m_nGroupID = nGroup;
- pRedirectInfo->m_nTrackID = nTrack;
- m_pRedirectList->AddTail(pRedirectInfo);
- cleanup:
- return theErr;
- }
- BOOL
- HXPlayer::IsAtSourceMap(SourceInfo* pSourceInfo)
- {
- SourceInfo* pResult = NULL;
- return m_pSourceMap->Lookup(pSourceInfo->m_pSource, (void*&)pResult);
- }
- /*
- * IHXErrorMessages methods
- */
- STDMETHODIMP
- HXPlayer::Report
- (
- const UINT8 unSeverity,
- HX_RESULT ulHXCode,
- const ULONG32 ulUserCode,
- const char* pUserString,
- const char* pMoreInfoURL
- )
- {
- /* Always pass through info and debug messages.
- * We use these severity levels for logging purposes and
- * do not consider them as errors
- */
- if (unSeverity == HXLOG_INFO ||
- unSeverity == HXLOG_DEBUG ||
- ulHXCode == HXR_OK)
- {
- return ActualReport(unSeverity, ulHXCode, ulUserCode,
- pUserString, pMoreInfoURL);
- }
- /* Do not override an error if it is already set.
- */
- if (m_LastError != HXR_OK)
- {
- m_bIsDone = TRUE;
- return HXR_OK;
- }
- m_LastSeverity = unSeverity;
- m_ulLastUserCode = ulUserCode;
- SetLastError(ulHXCode);
- if (pUserString != m_pLastUserString)
- {
- HX_VECTOR_DELETE(m_pLastUserString);
- if (pUserString && *pUserString)
- {
- m_pLastUserString = new char[strlen(pUserString) + 1];
- ::strcpy(m_pLastUserString, pUserString); /* Flawfinder: ignore */
- }
- }
- if (pMoreInfoURL != m_pLastMoreInfoURL)
- {
- HX_VECTOR_DELETE(m_pLastMoreInfoURL);
- if (pMoreInfoURL && *pMoreInfoURL)
- {
- m_pLastMoreInfoURL = new char[strlen(pMoreInfoURL) + 1];
- ::strcpy(m_pLastMoreInfoURL, pMoreInfoURL); /* Flawfinder: ignore */
- }
- }
- m_bIsDone = TRUE;
- m_bIsPresentationClosedToBeSent = TRUE;
- m_pAudioPlayer->DonePlayback();
- return HXR_OK;
- }
- HX_RESULT
- HXPlayer::ActualReport
- (
- const UINT8 unSeverity,
- HX_RESULT ulHXCode,
- const ULONG32 ulUserCode,
- const char* pUserString,
- const char* pMoreInfoURL
- )
- {
- #if defined(HELIX_FEATURE_SINKCONTROL)
- if (m_pErrorSinkControl)
- {
- m_pErrorSinkControl->ErrorOccurred(unSeverity, ulHXCode,
- ulUserCode, pUserString,
- pMoreInfoURL);
- }
- #endif /* HELIX_FEATURE_SINKCONTROL */
- return HXR_OK;
- }
- STDMETHODIMP_ (IHXBuffer*)
- HXPlayer::GetErrorText(HX_RESULT ulHXCode)
- {
- #if defined(HELIX_FEATURE_RESOURCEMGR)
- return m_pEngine->GetResMgr()->GetErrorString(ulHXCode);
- #else
- return NULL;
- #endif /* HELIX_FEATURE_RESOURCEMGR */
- }
- /************************************************************************
- * Method:
- * IHXAudioPlayerResponse::OnTimeSync
- * Purpose:
- * Notification interface provided by users of the IHXAudioPlayer
- * interface. This method is called by the IHXAudioPlayer when
- * audio playback occurs.
- */
- STDMETHODIMP HXPlayer::OnTimeSync(ULONG32 /*IN*/ ulCurrentTime)
- {
- HX_RESULT theErr = HXR_OK;
- CHXMapPtrToPtr::Iterator ndxSource;
- m_bCurrentPresentationClosed = FALSE;
- if (!m_bInitialized)
- return HXR_NOT_INITIALIZED;
- m_bTimeSyncLocked = TRUE;
- UpdateCurrentPlayTime( ulCurrentTime );
- if (m_bIsFirstTimeSync)
- {
- m_bIsFirstTimeSync = FALSE;
- m_ulFirstTimeSync = m_ulCurrentPlayTime;
- }
- // dfprintf("buff", "OnTimesync: %lu %lu %lun", HX_GET_TICKCOUNT(), m_ulCurrentPlayTime, m_ulCurrentSystemPlayTime);
- theErr = ProcessIdle();
- m_pCoreMutex->Lock();
- if (m_bCurrentPresentationClosed)
- {
- goto exit;
- }
- #if defined(HELIX_FEATURE_NESTEDMETA)
- m_pPersistentComponentManager->OnTimeSync(m_ulCurrentPlayTime);
- #endif /* HELIX_FEATURE_NESTEDMETA */
- ndxSource = m_pSourceMap->Begin();
- for (; !theErr && ndxSource != m_pSourceMap->End(); ++ndxSource)
- {
- SourceInfo* pSourceInfo = (SourceInfo *)(*ndxSource);
- pSourceInfo->OnTimeSync(m_ulCurrentPlayTime);
- if (pSourceInfo->m_pPeerSourceInfo &&
- pSourceInfo->m_pPeerSourceInfo->IsInitialized())
- {
- pSourceInfo->m_pPeerSourceInfo->OnTimeSync(m_ulCurrentPlayTime);
- }
- if (m_bCurrentPresentationClosed)
- {
- goto exit;
- }
- }
- if (m_BufferingReason == BUFFERING_SEEK || m_BufferingReason == BUFFERING_LIVE_PAUSE)
- {
- m_BufferingReason = BUFFERING_CONGESTION;
- if (m_pAdviseSink)
- {
- m_pAdviseSink->OnPostSeek(m_ulTimeBeforeSeek, m_ulTimeAfterSeek);
- }
- }
- if (m_pAdviseSink)
- {
- m_pAdviseSink->OnPosLength( (m_bIsLive ||
- m_ulCurrentPlayTime <= m_ulPresentationDuration) ?
- m_ulCurrentPlayTime : m_ulPresentationDuration,
- m_ulPresentationDuration);
- }
- m_bTimeSyncLocked = FALSE;
- exit:
- m_pCoreMutex->Unlock();
- return theErr;
- }
- HX_RESULT HXPlayer::DoURLOpen(CHXURL* pCHXURL, char* pMimeType)
- {
- HX_RESULT theErr = HXR_OK;
- char* pAltURL = NULL;
- if (!pCHXURL)
- {
- return HXR_UNEXPECTED;
- }
- char* pURL = (char*) pCHXURL->GetURL();
- if (!pURL || !*pURL)
- {
- return HXR_UNEXPECTED;
- }
- ResetError();
- ResetRedirectList();
- m_bCoreLocked = TRUE;
- m_pCoreMutex->Lock();
- #ifdef _RAHULDEBUG
- CHXURL::TestCompressURL(); // in chxurl.h
- #endif
- /* Validate the URL */
- theErr = pCHXURL->GetLastError();
- if (theErr)
- {
- goto exit;
- }
- /* If we are not in a STOP state, do an internal stop */
- if (!m_bIsPresentationDone)
- {
- // m_bIsPresentationClosedToBeSent = FALSE;
- StopPlayer(END_STOP);
- }
- m_bIsDone = FALSE;
- m_bIsPresentationDone = FALSE;
- m_bIsPresentationClosedToBeSent = TRUE;
- #if defined(HELIX_FEATURE_AUTOUPGRADE)
- HX_RELEASE (m_pUpgradeCollection);
- m_pUpgradeCollection = new HXUpgradeCollection;
- m_pUpgradeCollection->AddRef();
- #endif /* HELIX_FEATURE_AUTOUPGRADE */
- #if defined(HELIX_FEATURE_RECORDCONTROL)
- m_bRecordServiceEnabled = IsRecordServiceEnabled();
- #endif
- // all presentation started with one track in a group
- theErr = SetSingleURLPresentation(pCHXURL);
- if (m_LastError && !theErr)
- {
- theErr = m_LastError;
- }
- if (theErr)
- {
- m_bIsPresentationClosedToBeSent = FALSE;
- ResetPlayer();
- #if defined(HELIX_FEATURE_VIDEO)
- /*
- * Let the site supplier know that we are done changing the layout.
- */
- if (m_pSiteSupplier && !m_bBeginChangeLayoutTobeCalled)
- {
- m_bBeginChangeLayoutTobeCalled = TRUE;
- m_pSiteSupplier->DoneChangeLayout();
- }
- #endif /* HELIX_FEATURE_VIDEO */
- }
- if (!theErr)
- {
- SchedulePlayer();
- }
- exit:
- if (theErr)
- {
- /* If no one has set the last error and there is no user string,
- * copy URL to the user string
- */
- if (!m_LastError && !m_pLastUserString && pURL)
- {
- m_pLastUserString = new char[strlen(pURL) + 1];
- strcpy(m_pLastUserString, pURL); /* Flawfinder: ignore */
- }
- SetLastError(theErr);
- }
- if (m_LastError)
- {
- /* Schedule a ProcessIdle callback. That is where the error
- * would be reported/ auto-upgrade will be requested.
- */
- m_bIsDone = FALSE;
- SchedulePlayer();
- m_bIsDone = TRUE;
- theErr = HXR_OK;
- }
- else
- {
- if (!m_bPlayStateNotified && m_pEngine)
- {
- m_bPlayStateNotified = TRUE;
- m_pEngine->NotifyPlayState(m_bPlayStateNotified);
- }
- }
- m_pCoreMutex->Unlock();
- m_bCoreLocked = FALSE;
- return (theErr);
- }
- /************************************************************************
- * Method:
- * IHXPlayer::OpenURL
- * Purpose:
- * Tell the player to open and URL.
- */
- STDMETHODIMP HXPlayer::OpenURL(const char* pURL)
- {
- // we want to protect against the TLC opening another URL
- if (m_bSetModal)
- {
- return HXR_OK;
- }
- HX_RESULT hr = HXR_OK;
- HX_RELEASE(m_pRequest);
- // get the compresses URL
- CHXURL url(pURL);
- pURL = url.GetURL();
- m_pRequest = new CHXRequest();
- if( m_pRequest )
- {
- m_pRequest->AddRef();
- m_pRequest->SetURL(url.GetURL());
- m_bActiveRequest = TRUE;
- if (m_pClientRequestSink)
- {
- m_pClientRequestSink->OnNewRequest(m_pRequest);
- }
- hr = DoURLOpen(&url, NULL);
- }
- else
- {
- hr = HXR_OUTOFMEMORY;
- }
- return hr;
- }
- /************************************************************************
- * Method:
- * IID_IHXPlayer2::OpenRequest
- * Purpose:
- * Call this method to open the IHXRequest
- */
- STDMETHODIMP HXPlayer::OpenRequest(IHXRequest* pRequest)
- {
- // we want to protect against the TLC opening another URL
- if (m_bSetModal)
- {
- return HXR_OK;
- }
- HX_RESULT hr = HXR_OK;
- const char* pURL = NULL;
- if (!pRequest)
- {
- return HXR_UNEXPECTED;
- }
- HX_RELEASE(m_pRequest);
- m_pRequest = pRequest;
- m_pRequest->AddRef();
- m_bActiveRequest = TRUE;
- // retrieve the URL
- if (HXR_OK != m_pRequest->GetURL(pURL))
- {
- return HXR_UNEXPECTED;
- }
- if (m_pClientRequestSink && m_pRequest)
- {
- m_pClientRequestSink->OnNewRequest(m_pRequest);
- }
- // get the compresses URL
- CHXURL url(pURL);
- pURL = url.GetURL();
- m_pRequest->SetURL(pURL);
- hr = DoURLOpen(&url, NULL);
- return hr;
- }
- /************************************************************************
- * Method:
- * IID_IHXPlayer2::GetRequest
- * Purpose:
- * Call this method to get the IHXRequest
- */
- STDMETHODIMP HXPlayer::GetRequest(REF(IHXRequest*) pRequest)
- {
- HX_RESULT hr = HXR_OK;
- pRequest = NULL;
- if (!m_pRequest)
- {
- hr = HXR_UNEXPECTED;
- goto cleanup;
- }
- pRequest = m_pRequest;
- pRequest->AddRef();
- cleanup:
- return hr;
- }
- ////////////////////////////
- //
- HX_RESULT
- HXPlayer::SetSingleURLPresentation(const CHXURL* pURL)
- {
- HX_RESULT theErr = HXR_OK;
- SourceInfo* pSourceInfo = NULL;
- IHXGroup* pGroup = NULL;
- IHXValues* pProperties = NULL;
- CHXBuffer* pValue = NULL;
- m_nGroupCount = 0;
- #if defined(HELIX_FEATURE_BASICGROUPMGR)
- // create group
- m_pGroupManager->CreateGroup(pGroup);
- // create track
- pProperties = new CHXHeader;
- pProperties->AddRef();
- pValue = new CHXBuffer();
- pValue->AddRef();
- char* url = (char*)pURL->GetEscapedURL();
- pValue->Set((BYTE*)url, strlen(url)+1);
- pProperties->SetPropertyCString("url", pValue);
- pGroup->AddTrack(pProperties);
- m_pGroupManager->AddGroup(pGroup);
- HX_RELEASE(pValue);
- HX_RELEASE(pProperties);
- HX_RELEASE(pGroup);