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

📄 srcinfo.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
					ulStreamStartTime,					m_pPlayer);	}	else	{	    m_pWallClock = (SharedWallClock*)pLookupResult;	    ulStreamStartTime = m_pWallClock->ResetStartTime(ulStreamStartTime);	}	m_pWallClock->AddUser(this);    }    HX_RELEASE(pValues);    HX_RELEASE(pWallClockName);    return ulStreamStartTime;}/* * -- LIVE SYNC SUPPORT -- * * Basic clean up support for wall clock object. Notice that after * calling RemoveUser, you can use the wall clock object since it * may get deleted... so we always reset our wall clock object * pointer to NULL. */voidSourceInfo::DoneWithWallClock(){    if (m_pWallClock)    {	m_pWallClock->RemoveUser(this);	m_pWallClock = NULL;    }}HX_RESULTSourceInfo::ProcessIdle(BOOL	    bIsFirst,		        ULONG32&    ulNumStreamsToBeFilled,		        BOOL&       bIsBuffering,		        UINT16&     uLowestBuffering,		        BOOL	    bPersistent){    HX_RESULT		theErr		    = HXR_OK;    CHXEvent*          pEvent              = NULL;    HXSource*          pSource             = NULL;    IHXPendingStatus*  pStatus             = NULL;    RendererInfo*       pRendInfo           = NULL;    IHXValues*         pHeader             = NULL;    HXStream*          pStream             = NULL;    IHXRenderer*       pRenderer           = NULL;    STREAM_INFO*        pStreamInfo         = NULL;    IHXPacket*         pPacket             = NULL;    UINT16              unStatusCode        = 0;    UINT16              unPercentDone       = 0;    UINT32		ulPacketTime	    = 0;    INT64		llActualPacketTime  = 0;    INT64		llLastExpectedPacketTime = 0;    IHXBuffer*         pStatusDesc         = NULL;    BOOL		bAtInterrupt	    = FALSE;    bAtInterrupt = m_pPlayer->m_pEngine->AtInterruptTime();    if (m_bStopped)    {	return HXR_OK;    }    /* Check if a source has not been initialized. This will happen     * ONLY when we start a new track in the mid of a presentation     */    if (!m_bInitialized)    {	/* Do not initialize source at interrupt time */	if (bAtInterrupt)	{	    ScheduleProcessCallback();	    return HXR_OK;	}	theErr = InitializeAndSetupRendererSites();	if (theErr || !m_bInitialized)	{	    return theErr;	}    }    if (m_bSeekPending)    {	m_bSeekPending = FALSE;		Pause();	Seek(m_ulSeekTime);	m_pSource->DoSeek(m_ulSeekTime);	Begin();    }    pSource = m_pSource;    pStatus = m_pStatus;    // don't start getting events till the player setup has been    // done       if (!m_pPlayer->m_bInitialized  || 	m_pPlayer->m_bSetupToBeDone || 	m_pPlayer->m_bPostSetupToBeDone)    {	return HXR_OK;    }        UINT16  uIndex	= 0;    BOOL    bHandled	= TRUE;    llLastExpectedPacketTime = m_pSource->GetLastExpectedPacketTime();    LISTPOSITION posRend = m_pCurrentScheduleList->GetHeadPosition();    for (; uIndex < m_pCurrentScheduleList->GetCount(); uIndex++)    {	BOOL	bSentMe = TRUE;	BOOL	bEndMe = FALSE;		llActualPacketTime = 0;		theErr = HXR_OK;	if (uIndex > 0)	{	    if (bHandled)	    {		posRend = m_pCurrentScheduleList->RemoveAt(posRend);		LISTPOSITION listRet = m_pCurrentScheduleList->AddTail(pRendInfo);                // This check is critical for catching oom errors. XXXJHHB                if( listRet == NULL )                {                    return HXR_OUTOFMEMORY;                }	    }	    else	    {		m_pCurrentScheduleList->GetNext(posRend);	    }	}	bHandled = TRUE;	pRendInfo       = (RendererInfo*) 			m_pCurrentScheduleList->GetAt(posRend);	pStreamInfo     = pRendInfo->m_pStreamInfo;	if (pStreamInfo->m_bSrcInfoStreamDone)	{	    // SPECIAL CASE:	    // the player received all the packets(m_bSrcStreamDone is TRUE) and 	    // EndOfPacket() hasn't been sent to the renderer yet, 	    // BUT the renderer still calls ReportRebufferStatus()		    if (!IsRebufferDone())	    {		bIsBuffering = TRUE;	    }	    else	    {		CheckIfDone();	    }	    continue;	}	if (bIsFirst)	{	    pStreamInfo->m_bSrcInfoStreamFillingDone = FALSE;	    ulNumStreamsToBeFilled++;	}	BOOL bThisSourceBuffering = FALSE;	if (!bPersistent)	{	    // every HXSource has to implement IID_IHXPendingStatus	    HX_ASSERT(pStatus);	    HX_VERIFY(HXR_OK == pStatus->GetStatus(unStatusCode, pStatusDesc,						   unPercentDone));	    HX_RELEASE(pStatusDesc);	    if ((HX_STATUS_BUFFERING == unStatusCode && unPercentDone < 100) ||		HX_STATUS_CONTACTING == unStatusCode)	    {		bIsBuffering            = TRUE;		bThisSourceBuffering    = TRUE;		if (uLowestBuffering > unPercentDone)		{		    uLowestBuffering = unPercentDone;		}	    }	}	/* the event times are actual ts - preroll.. so we do not	 * need to add preroll in calculations here...	 */	  	 	UINT32 ulDeliveryTime = m_pPlayer->m_ulCurrentPlayTime + 	    			   m_pPlayer->m_ulLowestGranularity;#ifdef _MACINTOSH#define ADDITIONAL_PREDELIVERY_TIME	4000 	/* on Mac we try to be even farther ahead than the timeline in 	 * packet delivery since the callbacks are not that smooth 	 * and if we are really close to the wire, it results in 	 * unnecccessary re-buffers.  	 */ 	ulDeliveryTime += ADDITIONAL_PREDELIVERY_TIME;#endif		if (pSource)	{	    pSource->FillRecordControl();	}	if (bPersistent || bThisSourceBuffering ||	    (pRendInfo->m_ulLatestEventTime <= ulDeliveryTime))	{	      	    theErr = pSource->GetEvent(pStreamInfo->m_uStreamNumber, pEvent);	    if (!theErr)	    {		pPacket = pEvent->GetPacket();		if (pEvent->IsPreSeekEvent())		{		     // associate the packet with its renderer..		     pEvent->m_pRendererInfo   = pRendInfo;		    		     if (!bAtInterrupt || pRendInfo->m_bInterruptSafe)		     {			 theErr = m_pPlayer->SendPacket(pEvent);			 delete pEvent;		     }		     else		     {			// insert event in the common packet/event list...			theErr = m_pPlayer->m_EventList.InsertEvent(pEvent);                        if( theErr == HXR_OUTOFMEMORY )                        {                            return HXR_OUTOFMEMORY;                        }			pRendInfo->m_ulNumberOfPacketsQueued++;		     }		     continue;		}		if (!pPacket->IsLost())		{		    ulPacketTime = pPacket->GetTime();		    llActualPacketTime = 			pRendInfo->m_pStreamInfo->BufferingState().CreateINT64Timestamp(ulPacketTime);		    if (m_llLatestPacketTime < llActualPacketTime)		    {			m_llLatestPacketTime = llActualPacketTime;		    }		    pRendInfo->m_ulLatestEventTime  = pEvent->GetTimeStartPos();		    		    if (pSource->IsLive() && pRendInfo->m_bIsFirstPacket)		    {			pRendInfo->m_bIsFirstPacket     = FALSE;			/*			 * -- LIVE SYNC SUPPORT --			 *			 * We used to just set the stream start time to the 			 * timestamp of this first packet. Now we use this			 * helper function to implement support for sharing			 * start times for sources off of the same wall clock.			 * See other LIVE SYNC SUPPORT comments for more 			 * details.			 */			UINT32 ulLiveStart = CalculateLiveStartTime(pPacket);			pRendInfo->m_ulStreamStartTime = ulLiveStart;			m_ulStreamStartTime = ulLiveStart;			UINT32  ulLowestTime = 0;			BOOL    bAtLeastOneLowestTime = FALSE;			UINT16  uNumLowestKnown = 0;			CHXMapLongToObj::Iterator tmpndxRend = m_pRendererMap->Begin();			for (;!theErr && tmpndxRend != m_pRendererMap->End();				++tmpndxRend)			{			    RendererInfo* pTmpRendInfo  = (RendererInfo*)(*tmpndxRend);			    /* Have we received the lowest packet?*/			    if (!pTmpRendInfo->m_bIsFirstPacket)			    {				uNumLowestKnown++;				if (!bAtLeastOneLowestTime)				{				    bAtLeastOneLowestTime = TRUE;				    ulLowestTime = pTmpRendInfo->m_ulStreamStartTime;				    SetLiveSyncStartTime(pSource, pTmpRendInfo, ulLowestTime);				}				else				{				    if (ulLowestTime > pTmpRendInfo->m_ulStreamStartTime)				    {					ulLowestTime = pTmpRendInfo->m_ulStreamStartTime;				    }				}			    }			}			if (uNumLowestKnown > 1)			{			    tmpndxRend = m_pRendererMap->Begin();			    for (;!theErr && tmpndxRend != m_pRendererMap->End();				    ++tmpndxRend)			    {				RendererInfo* pTmpRendInfo      = (RendererInfo*)(*tmpndxRend);				/* Have we received the lowest packet?*/				if (!pTmpRendInfo->m_bIsFirstPacket)				{				    pTmpRendInfo->m_ulStreamStartTime = ulLowestTime;				    SetLiveSyncStartTime(pSource, pTmpRendInfo, ulLowestTime);				}			    }			}		    }		    if ((!pSource->IsLive() || pSource->isRestrictedLiveStream()) &&			llActualPacketTime > llLastExpectedPacketTime)		    {			// XXX HP			// work around since the rule flag of all RTSP packets are set to			// HX_ASM_SWITCH_ON only and this could cause the stream doesn't end 			// properly if its endtime was changed after the first resume has been 			// sent			// THIS WILL BE FIXED IN THE NEXT SERVER RELEASE("dial-tone")  			if (pSource->m_bRTSPRuleFlagWorkAround)			{			    bSentMe = FALSE;			    bEndMe = TRUE;			}			else 			{			    pRendInfo->m_pStream->PostEndTimePacket(pPacket, bSentMe, bEndMe);			}		    }		}		    		if (bSentMe)		{		    		    // clear up the post events which were not sent		    if (pStreamInfo->m_pPostEndTimeEventList)		    {			while (pStreamInfo->m_pPostEndTimeEventList->GetNumEvents())			{			    CHXEvent* pPostEndTimeEvent = pStreamInfo->m_pPostEndTimeEventList->RemoveHead();			    // associate the packet with its renderer..			    pPostEndTimeEvent->m_pRendererInfo   = pRendInfo;			    // insert event in the common packet/event list...			    theErr = m_pPlayer->m_EventList.InsertEvent(pPostEndTimeEvent);                            if( theErr == HXR_OUTOFMEMORY )                            {                                return HXR_OUTOFMEMORY;			    }			    pRendInfo->m_ulNumberOfPacketsQueued++;			}		    }		    // associate the packet with its renderer..		    pEvent->m_pRendererInfo   = pRendInfo;		    // insert event in the common packet/event list...		    theErr = m_pPlayer->m_EventList.InsertEvent(pEvent);		    if( theErr == HXR_OUTOFMEMORY )                    {                        return HXR_OUTOFMEMORY;		    }		    pRendInfo->m_ulNumberOfPacketsQueued++;		}		else		{		    if (!pStreamInfo->m_pPostEndTimeEventList)		    {			pStreamInfo->m_pPostEndTimeEventList = new CHXEventList();		    }		    if (pStreamInfo->m_pPostEndTimeEventList)		    {//{FILE* f1 = ::fopen("c:\\temp\\out.txt", "a+"); ::fprintf(f1, "bSentMe is FALSE PacketTime: %lu PacketRule: %u\n", pEvent->GetPacket()->GetTime(), pEvent->GetPacket()->GetASMRuleNumber());::fclose(f1);}						theErr = pStreamInfo->m_pPostEndTimeEventList->InsertEvent(pEvent);			if( theErr == HXR_OUTOFMEMORY )			{			    return theErr;			}		    }		}	    }	    else	    {		bHandled = FALSE;	    }	    if (theErr && !bPersistent)	    {		if (!pStreamInfo->m_bSrcInfoStreamFillingDone &&		    ulNumStreamsToBeFilled > 0)		{		    pStreamInfo->m_bSrcInfoStreamFillingDone = TRUE;		    ulNumStreamsToBeFilled--;		}	    }	}	else	{	    if (!pStreamInfo->m_bSrcInfoStreamFillingDone &&		ulNumStreamsToBeFilled > 0)	    {		pStreamInfo->m_bSrcInfoStreamFillingDone = TRUE;		ulNumStreamsToBeFilled--;	    }	}	if (theErr == HXR_BUFFERING)	{	    if (bPersistent)	    {		bIsBuffering    = TRUE;	    }	}	else if (theErr == HXR_AT_END)	{	    if (!pStreamInfo->m_bSrcInfoStreamDone)	    {		if (!bAtInterrupt || pRendInfo->m_bInterruptSafe)		{		    pStreamInfo->m_bSrcInfoStreamDone = TRUE;		    pStreamInfo->ResetPostEndTimeEventList();		    if (pRendInfo->m_ulNumberOfPacketsQueued == 0 &&			pRendInfo->m_pRenderer)		    {						m_pPlayer->SendPostSeekIfNecessary(pRendInfo);			pRendInfo->m_pRenderer->OnEndofPackets();			pRendInfo->m_bOnEndOfPacketSent = TRUE;			    }		    CheckIfDone();		}		else		{		    ScheduleProcessCallback();		    continue;		}	    }	}	else if (theErr == HXR_NO_DATA)	{	    /* mask this error */	    theErr  = HXR_OK;	}	if (!llActualPacketTime)	{	    STREAM_INFO* pStrInfo = pRendInfo->m_pStreamInfo;	    UINT32 ulPktTime = 		pStrInfo->BufferingState().LastPacketTimestamp();	    llActualPacketTime = 		pStrInfo->BufferingState().CreateINT64Timestamp(ulPktTime);	    	    /* if this is a stream where we do not have to wait to receive 	     * a packet >= stream's last expected packet time, 	     * make the highest timestamp to be the HIGHEST timestamp	     * across ALL streams for this source.	     *	     * This is to fix end tag support on sources with sparse streams	     * e.g. audio/video with an event stream where we may not really 	     * have a packet till way down in the future.  	     */ 	    if (pRendInfo->m_pStreamInfo->m_bCanBeStoppedAnyTime &&		!pStreamInfo->m_bSrcInfoStreamDone &&		m_llLatestPacketTime > llLastExpectedPacketTime)	    {		/* check if ALL other streams have ended */		if (AllOtherStreamsHaveEnded(pStreamInfo))		{                    /*                     * The logic above was designed to handle endTime's                     * on a/v streams, so that once we received a/v packets                     * past the end time (even though more packets are                      * still coming in), we can go ahead and end the                     * event stream. However, this was causing a bug                     * where syncmm event streams were getting terminated                     * even though there was a packet waiting for it                     * at the transport. This additional test imposes

⌨️ 快捷键说明

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