⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 srcinfo.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* ***** 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"
#include "hxcom.h"
#include "hxresult.h"
#include "smiltype.h"
#include "hxcomm.h"		// IHXRegistryID
#include "hxengin.h"
#include "hxcore.h"
#include "hxupgrd.h"
#include "hxrendr.h"
#include "hxasm.h"
#include "hxsmbw.h"
#include "hxgroup.h"
#include "hxausvc.h"
#include "hxslist.h"
#include "hxmap.h"
#include "chxpckts.h"
#include "chxeven.h"
#include "chxelst.h"
#include "strminfo.h"

#include "timeval.h"
#include "hxbsrc.h"
#include "hxsrc.h"
#include "hxstrm.h"
#include "hxsmstr.h"
#include "hxaudply.h"
#include "basgroup.h"
#include "advgroup.h"
#include "hxthread.h"
#include "hxtick.h"
#include "hxstrutl.h"

#include "srcinfo.h"
#include "hxplay.h"
#include "hxcleng.h"
#include "plghand2.h"

#include "hxheap.h"
#ifdef _DEBUG
#undef HX_THIS_FILE		
static const char HX_THIS_FILE[] = __FILE__;
#endif

#define TIME_SYNC_FUDGE_FACTOR      10
#define GOTOEXITONERROR(theErr, label)      if ((theErr) != 0) goto label

SourceInfo::SourceInfo(HXPlayer* pPlayer)
{
    m_pRendererMap = new CHXMapLongToObj;
    
    m_pPlayer = pPlayer;
    m_pPlayer->AddRef();
    m_pSource		    = NULL;
    m_bDone		    = FALSE;
    m_bStopped		    = FALSE;
    m_bInitialized	    = FALSE;
    m_pStatus		    = NULL;
    m_bAllPacketsReceived   = FALSE;
    m_bActive		    = TRUE;
    m_bIsPersistentSource   = FALSE;
    m_bIsRegisterSourceDone = FALSE;
    m_uTrackID		    = 0;
    m_uGroupID		    = 0;
    m_bToBeResumed	    = TRUE;
    m_bAreStreamsSetup	    = FALSE;
    m_bTrackStartedToBeSent = TRUE;
    m_bTrackStoppedToBeSent = TRUE;
    m_bPrefetch		    = FALSE;
    m_bLoadPluginAttempted  = FALSE;
    m_pCurrentScheduleList  = NULL;
    m_ulSourceDuration	    = 0;
    m_ulMaxDuration	    = 0;
    m_ulTrackDuration	    = 0;
    m_ulTotalTrackDuration  = 0;
    m_pDependNode	    = NULL;
    m_uNumDependencies	    = 0;
    m_bTobeInitializedBeforeBegin = FALSE;
    m_bAltURL		    = FALSE;
    m_lastErrorFromMainURL  = HXR_OK;
    m_lastError             = HXR_OK;
    m_bLocked		    = FALSE;
    m_bIsTrackDurationSet   = FALSE;
    m_bDurationTimeSyncScheduled = FALSE;
    m_bAudioDeviceReflushHint = FALSE;
    m_pProcessCallback = new CHXGenericCallback((void*)this, (fGenericCBFunc)ProcessCallback);
    m_pProcessCallback->AddRef();

    m_prefetchType = PrefetchUnknown;
    m_ulPrefetchValue = 0;
    m_uSoundLevel = 100;
    m_fillType = FillRemove;

    m_pPeerSourceInfo = NULL;   
    m_bSeekPending = FALSE;
    m_bIndefiniteDuration = FALSE;
    m_bRepeatIndefinite = FALSE;
    m_bSeekToLastFrame = FALSE;
    m_ulRepeatInterval = 0;
    m_ulRepeatDelayTimeOffset = 0;
    m_ulSeekTime = 0;
    m_ulPausedStartTime = 0;

    m_bLeadingSource = TRUE;
    m_bRepeatPending = FALSE;
    m_pRepeatList = NULL;
    m_curPosition = 0;
    
    m_ulPersistentComponentID = MAX_UINT32;
    m_ulPersistentComponentSelfID = MAX_UINT32;
    m_pRendererAdviseSink = NULL;

#ifdef THREADS_SUPPORTED
    HXMutex::MakeMutex(m_pMutex);
#else
    HXMutex::MakeStubMutex(m_pMutex);
#endif

    /*
     * The following members are needed for live sync support.
     */
    m_pWallClock = NULL;
    m_ulStreamStartTime = 0;
    m_llLatestPacketTime    = 0;
}

SourceInfo::~SourceInfo()
{
    if (m_pProcessCallback && m_pPlayer->m_pScheduler)
    {
	m_pPlayer->m_pScheduler->Remove(m_pProcessCallback->GetPendingCallback());
        m_pProcessCallback->CallbackCanceled();
    }

    if (m_pRepeatList)
    {
	while (m_pRepeatList->GetCount())
	{
	    RepeatInfo* pRepeatInfo = (RepeatInfo*)m_pRepeatList->RemoveHead();
	    HX_DELETE(pRepeatInfo);
	}

	HX_DELETE(m_pRepeatList);
    }

    HX_RELEASE(m_pStatus);
    HX_RELEASE(m_pProcessCallback);
    HX_RELEASE(m_pPlayer);
    HX_DELETE(m_pCurrentScheduleList);
    HX_VECTOR_DELETE(m_pDependNode);
    HX_DELETE(m_pMutex);

    HX_DELETE(m_pRendererMap);
    /*
     * For live sync support, we may have used a shared wall
     * clock, if so then we're done with it now, so we may need 
     * to do some cleanup work here.     
     */
    DoneWithWallClock();
};



HX_RESULT
SourceInfo::Begin()
{
    HX_RESULT theErr = HXR_OK;

    if(!m_pSource || !m_pSource->IsInitialized())
    {
	return HXR_OK;
    }

    if (m_pPlayer->m_bInitialized)
    {
	// handle the seek so that the server will be notified 
	// via the play request upon the first resume
	if (m_bSeekPending)
	{
	    m_bSeekPending = FALSE;
	
	    Pause();
	    Seek(m_ulSeekTime);
	    m_pSource->DoSeek(m_ulSeekTime);
	}

	theErr = m_pSource->DoResume();
    }

    if (!m_bInitialized)
    {
	return HXR_OK;
    }

    /* 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 (!m_pPlayer->m_bIsFirstBegin && !m_pPlayer->m_bInternalPauseResume)
    {
	CHXMapLongToObj::Iterator ndxRend = m_pRendererMap->Begin();
	for (; !theErr &&
		ndxRend != m_pRendererMap->End(); ++ndxRend)
	{
	    RendererInfo* pRendInfo = (RendererInfo*) (*ndxRend);

	    if (!pRendInfo->m_bInitialBeginToBeSent)
	    {
		IHXRenderer* pRend  = (IHXRenderer*) pRendInfo->m_pRenderer;
		pRend->OnBegin(m_pPlayer->m_ulCurrentPlayTime);
	    }
	}
    }

    return theErr;
}


HX_RESULT
SourceInfo::Pause()
{
    HX_RESULT	theErr	= HXR_OK;

    if(!m_pSource)
    {
	return HXR_OK;
    }

    theErr = m_pSource->DoPause();

    /* Do not send OnPause to renderers if it is an internal Pause */
    if (m_pPlayer->m_bInternalPauseResume || !m_bInitialized)
    {
	return theErr;
    }

    CHXMapLongToObj::Iterator ndxRend = m_pRendererMap->Begin();
    for (; !theErr &&
	    ndxRend != m_pRendererMap->End(); ++ndxRend)
    {
	RendererInfo* pRendInfo = (RendererInfo*) (*ndxRend);
	IHXRenderer* pRend     = (IHXRenderer*) pRendInfo->m_pRenderer;

	m_pPlayer->m_pScheduler->Remove(
         pRendInfo->m_pTimeSyncCallback->GetPendingCallback());
        
        pRendInfo->m_pTimeSyncCallback->CallbackCanceled();
	pRendInfo->m_bIsFirstCallback   = TRUE;

	pRend->OnPause(m_pPlayer->m_ulCurrentPlayTime);
    }

    return theErr;
}


HX_RESULT
SourceInfo::Seek(UINT32 ulSeekTo)
{
    HX_RESULT			    rc = HXR_OK;
    INT64			    llLastExpectedPacketTime = 0;
    BOOL			    bSeekToLastFrame = FALSE;
    BOOL			    bDurationTimeSyncSent = TRUE;
    UINT32			    ulValue = 0;
    RendererInfo*		    pRendInfo = NULL;
    STREAM_INFO*		    pStreamInfo = NULL;
    IHXValues*			    pStatus = NULL;
    IHXPersistentRenderer*	    pPersRender = NULL;
    IHXPersistentComponent*	    pPersComp = NULL;
    HXPersistentComponentManager*  pPersCompMgr = NULL;
    CHXMapLongToObj::Iterator ndx;

    /* m_pSource should never be NULL */
    HX_ASSERT(m_pSource);
    if(!m_pSource || !m_bInitialized)
    {
	return HXR_OK;
    }

    m_bDone = FALSE;
    m_bActive = TRUE;
    m_bAllPacketsReceived = FALSE;
    llLastExpectedPacketTime = m_pSource->GetLastExpectedPacketTime();

    /* Are we seeking past the last expected packet time?
     * If so, verify the "show" attribute to see whether we need to
     * get the last video frame
     */    
    if (!m_pSource->IsLive() && ulSeekTo >= INT64_TO_UINT32(llLastExpectedPacketTime + m_pSource->GetDelay()))
    {
#if defined(HELIX_FEATURE_NESTEDMETA)
	pPersCompMgr = m_pPlayer->m_pPersistentComponentManager;
	if (FillFreeze == m_fillType && pPersCompMgr) 
	{
	    rc = pPersCompMgr->GetPersistentComponent(m_ulPersistentComponentID,
						      pPersComp);
	    HX_ASSERT(HXR_OK == rc);

	    if (pPersComp)
	    {
		rc = pPersComp->GetPersistentRenderer(pPersRender);
		HX_ASSERT(HXR_OK == rc);

		rc = pPersRender->GetElementStatus(m_uGroupID,
						   m_uTrackID,
						   ulSeekTo,
						   pStatus);
		HX_ASSERT(HXR_OK == rc);

		if (pStatus && HXR_OK == pStatus->GetPropertyULONG32("Show", ulValue))
		{
		    bSeekToLastFrame = (BOOL)ulValue;
		}

		HX_RELEASE(pStatus);
		HX_RELEASE(pPersRender);
		HX_RELEASE(pPersComp);
	    }
	}
	else if (FillHold == m_fillType)
	{
	    bSeekToLastFrame = TRUE;
	}
#else
	if (FillHold == m_fillType)
	{
	    bSeekToLastFrame = TRUE;
	}
#endif /* HELIX_FEATURE_NESTEDMETA */
    }

    // also check if we already sent OnTimeSync() upon its duration ends
    // which means the renderer got the last frame so we don't need to issue
    // last frame seek
    if (bSeekToLastFrame)
    {
	ndx = m_pRendererMap->Begin();
	for (; ndx != m_pRendererMap->End(); ++ndx)
	{
	    pRendInfo = (RendererInfo*)(*ndx);
	    if (!pRendInfo->m_bDurationTimeSyncSent)
	    {
		bDurationTimeSyncSent = FALSE;
	    }
	}

	if (bDurationTimeSyncSent)
	{
	    bSeekToLastFrame = FALSE;
	}
    }

    CHXMapLongToObj::Iterator ndxRend = m_pRendererMap->Begin();
    for (; ndxRend != m_pRendererMap->End(); ++ndxRend)
    {
	RendererInfo* pRendInfo     = (RendererInfo*)(*ndxRend);
	IHXRenderer* pRend         = (IHXRenderer*)pRendInfo->m_pRenderer;
	STREAM_INFO*  pStreamInfo   = pRendInfo->m_pStreamInfo;
	
	pStreamInfo->m_bSrcInfoStreamDone  = FALSE;

	pRendInfo->m_pStream->ResetASMRuleState();
	pStreamInfo->ResetPostEndTimeEventList();

	if (m_pSource->IsLive())
	{
#if defined(HELIX_FEATURE_RECORDCONTROL)
	    if(m_pSource->IsPlayingFromRecordControl())
	    {
		pStreamInfo->m_ulTimeBeforeSeek = m_pPlayer->m_ulTimeBeforeSeek;
		pStreamInfo->m_ulTimeAfterSeek = m_pPlayer->m_ulTimeAfterSeek;

		if (pRendInfo->m_bTimeDiffPositive)
		{
		    pStreamInfo->m_ulTimeBeforeSeek += pRendInfo->m_ulTimeDiff;
		    pStreamInfo->m_ulTimeAfterSeek += pRendInfo->m_ulTimeDiff;
		}
		else
		{
		    pStreamInfo->m_ulTimeBeforeSeek -= pRendInfo->m_ulTimeDiff;
		    pStreamInfo->m_ulTimeAfterSeek -= pRendInfo->m_ulTimeDiff;
		}
	    }
	    else
#endif /* HELIX_FEATURE_RECORDCONTROL */
	    {
		UINT32 ulLastTimeSync = (LONG32) m_pPlayer->m_ulLiveSeekTime;

		if (pRendInfo->m_bTimeDiffPositive)
		{
		    ulLastTimeSync += pRendInfo->m_ulTimeDiff;
		}
		else
		{
		    ulLastTimeSync -= pRendInfo->m_ulTimeDiff;
		}

		pStreamInfo->m_ulTimeBeforeSeek = ulLastTimeSync;
		pStreamInfo->m_ulTimeAfterSeek  = ulLastTimeSync + m_pPlayer->m_ulElapsedPauseTime;
	    }
	}
	else
	{
	    pStreamInfo->m_ulTimeBeforeSeek = m_pPlayer->m_ulTimeBeforeSeek;
	    if (bSeekToLastFrame)
	    {		
		HX_ASSERT(llLastExpectedPacketTime + m_pSource->GetDelay() >= 1);
		pStreamInfo->m_ulTimeAfterSeek = INT64_TO_UINT32(llLastExpectedPacketTime + m_pSource->GetDelay() - 1);
	    }
	    else
	    {
		pStreamInfo->m_ulTimeAfterSeek = m_pPlayer->m_ulTimeAfterSeek;
	    }
	}
	
	pRend->OnPreSeek(pStreamInfo->m_ulTimeBeforeSeek,
			 pStreamInfo->m_ulTimeAfterSeek);

	pStreamInfo->m_pStream->m_bPostSeekToBeSent = TRUE;

	// reset renderer info attributes 
	pRendInfo->m_ulLatestEventTime	    = 0;
	pRendInfo->m_bIsFirstCallback	    = TRUE;
	pRendInfo->m_ulLastSyncTime         = 0;
	pRendInfo->m_ulNextDueSyncTime      = m_pPlayer->m_ulCurrentPlayTime;

	/* Do we need to send a time sync for renderer duration? */
	if (bSeekToLastFrame || pRendInfo->m_ulNextDueSyncTime <= pRendInfo->m_ulDuration)
	{
	    pRendInfo->m_bDurationTimeSyncSent  = FALSE;
	    pRendInfo->m_bOnEndOfPacketSent = FALSE;
	}
	else
	{
	    pRendInfo->m_bDurationTimeSyncSent  = TRUE;
	}

	m_pPlayer->m_pScheduler->Remove(
         pRendInfo->m_pTimeSyncCallback->GetPendingCallback());
        
        pRendInfo->m_pTimeSyncCallback->CallbackCanceled();

	if (!pRendInfo->m_bInitialBeginToBeSent)
	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -