📄 hxntsrc.cpp
字号:
// to not reset variables related to stream completeness.
m_pBufferManager->DoSeek(seekTime, bSeekInsideRecordControl);
cleanup:
return HXR_OK;
}
HX_RESULT
HXNetSource::DoPause(void)
{
HX_TRACE("HXNetSource::DoPause");
if (!m_pProto || m_bPaused)
{
return HXR_OK;
}
// log pause action
LogInformation("PAUSE", NULL);
m_pBufferManager->DoPause();
if (m_pBufferCtl)
{
m_pBufferCtl->OnPause();
}
m_bPaused = TRUE;
if (m_bPlayFromRecordControl && !m_bDelayed)
{
return HXR_OK;
}
/* Do not call pause if the source has ended. In RTSP, if the transport
* is paused, it does not give us any packets. We would never issue a
* resume since the source has ended and this would result in starting
* the playback without giving any packets to the renderer if the preroll
* of the renderer happens to be zero.(like RealText).
*/
/* Call Pause even after source is done. This is to keep track
* of Accounting information on the server side for PPV content
* The only time we do not issue a pause is if we have internally
* stopped the stream because of a end/dur tag.
*
* RTSP transport has been fixed so that it returns packets even
* in a paused state. So the bug reported above should not occur.
* Moreover, we now call protocol Resume even if the source is done.
* So the transport should never be really in a Paused state when
* we need to read packets.
*/
if (!m_bForcedSourceEnd)
{
m_pProto->pause();
#if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
if (m_pStatsCallback)
{
m_pStatsCallback->PauseCallback();
}
#endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
}
return HXR_OK;
}
HX_RESULT
HXNetSource::StartInitialization(void)
{
if (m_pProto)
{
m_bUserHasCalledStartInit = TRUE;
m_pBufferManager->DoResume();
if (m_pSourceInfo)
{
m_pSourceInfo->Resumed();
/* This is temporary. The source MUST be registered by this point.
* Fix it after B1.
* For now, added a work around
* - Rahul
*/
if (!m_pSourceInfo->IsRegistered() && m_pSourceInfo->IsActive())
{
m_pSourceInfo->Register();
if (m_pPlayer)
{
m_pPlayer->RegisterSourcesDone();
}
}
}
SetNoLatency();
HX_ASSERT(m_llLastExpectedPacketTime <= MAX_UINT32);
#if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
if (m_bSendStatistics && m_ulStatsInterval > 0)
{
if (!m_pStatsCallback)
{
m_pStatsCallback = new ReconnectCallback(this, TRUE);
m_pStatsCallback->AddRef();
}
if (m_pStatsCallback->IsPaused())
{
m_pStatsCallback->ResumeCallback();
}
else
{
m_pStatsCallback->ScheduleCallback(m_ulStatsInterval);
}
}
#endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
return m_pProto->resume(INT64_TO_UINT32(m_llLastExpectedPacketTime));
}
return HXR_OK;
}
HX_RESULT
HXNetSource::DoResume(void)
{
HX_TRACE("HXNetSource::DoResume");
HX_RESULT theErr = HXR_OK;
/* This may happen if a new source is added from SMIL renderer during
* initialization of exisitng sources. We will eventually call Resume
* on this source once it is initialized in SourceInfo::ProcessIdle
*/
if (!m_bInitialized)
{
return HXR_OK;
}
m_bUserHasCalledResume = TRUE;
// log resume action
LogInformation("Resume", NULL);
if(m_pBufferManager && !m_bSourceEnd && CanBeResumed())
{
m_pBufferManager->DoResume();
}
/* Call Resume even after source is done. This is to keep track
* of Accounting information on the server side for PPV content
* Only if we have forced a source end because of end/dur tag
* or because of seeking past source's duration in SMIL,
* we do not send Pause/Resume to the server
*/
if (!m_pProto || (!m_bPaused && !m_bFirstResume))
{
return HXR_OK;
}
if(m_bPlayFromRecordControl && !m_bDelayed && !m_bFirstResume && !m_bResumePending)
{
m_bPaused = FALSE;
return HXR_OK;
}
if (m_bSourceEnd || CanBeResumed())
{
m_bResumePending = FALSE;
HX_ASSERT(m_pSourceInfo);
if (!m_bSourceEnd)
{
/* This is temporary. This assert is currently tripping...
* Ideally, it should not. Fix it after B1.
* For now, added a work around
* - Rahul
*/
// HX_ASSERT(!m_pSourceInfo || m_pSourceInfo->IsRegistered() || !m_pSourceInfo->IsActive());
if (m_pSourceInfo && !m_pSourceInfo->IsRegistered() && m_pSourceInfo->IsActive())
{
m_pSourceInfo->Register();
if (m_pPlayer)
{
m_pPlayer->RegisterSourcesDone();
}
}
SetNoLatency();
if (m_bBruteForceReconnected && m_bSeekPending)
{
theErr = m_pProto->seek(m_ulSeekPendingTime);
}
HX_ASSERT(INT64_TO_ULONG32(m_llLastExpectedPacketTime) <= MAX_UINT32);
theErr = m_pProto->resume(INT64_TO_UINT32(m_llLastExpectedPacketTime));
#if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
if (m_bSendStatistics && m_ulStatsInterval > 0)
{
if (!m_pStatsCallback)
{
m_pStatsCallback = new ReconnectCallback(this, TRUE);
m_pStatsCallback->AddRef();
}
if (m_pStatsCallback->IsPaused())
{
m_pStatsCallback->ResumeCallback();
}
else
{
m_pStatsCallback->ScheduleCallback(m_ulStatsInterval);
}
}
#endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
}
// resume the audio streams if the source is added
// while the player is in play
// CAUTION: this will cause rewind in audio service
if (m_bFirstResume &&
IsPlaying() &&
(m_state == NETSRC_READY) &&
m_pPlayer && m_ulDelay <= m_pPlayer->GetInternalCurrentPlayTime())
{
ResumeAudioStreams();
}
m_bFirstResume = FALSE;
m_bPaused = FALSE;
if (m_pSourceInfo)
{
m_pSourceInfo->Resumed();
}
if (m_pBufferCtl)
{
m_pBufferCtl->OnResume();
}
}
if (!m_bIsActive && !m_bDelayed && m_pPlayer &&
m_pPlayer->GetInternalCurrentPlayTime() >= m_ulDelay)
{
AdjustClipBandwidthStats(TRUE);
}
return theErr;
}
/************************************************************************
* Method:
* IHXPendingStatus::GetStatus
* Purpose:
* Called by the user to get the current pending status from an object
*/
STDMETHODIMP
HXNetSource::GetStatus
(
REF(UINT16) uStatusCode,
REF(IHXBuffer*) pStatusDesc,
REF(UINT16) ulPercentDone
)
{
HX_RESULT rc = HXR_OK;
UINT16 buffer = 100;
UINT16 statusCode = HX_STATUS_READY;
UINT16 percentDone = 0;
/* Default values*/
uStatusCode = statusCode;
pStatusDesc = NULL;
ulPercentDone = buffer;
UINT16 uSrcPercentDone = 100;
UINT16 uSrcStatusCode = HX_STATUS_READY;
if (m_bDelayed)
{
goto cleanup;
}
#if defined(HELIX_FEATURE_TURBOPLAY)
if (m_bFastStart &&
m_bRARVSource &&
(!m_pSourceInfo || !m_pSourceInfo->m_bIsPersistentSource))
{
if (HXR_OK == IsFaststartPushdownFullfilled(uStatusCode, ulPercentDone))
{
goto cleanup;
}
}
#endif /* HELIX_FEATURE_TURBOPLAY */
if (m_bSourceEnd)
{
if (!IsRebufferDone())
{
uStatusCode = HX_STATUS_BUFFERING;
ulPercentDone = 99;
}
else
{
if (m_bInitialBuffering)
{
InitialBufferingDone();
}
m_uLastBuffering = 100;
uStatusCode = HX_STATUS_READY;
}
goto cleanup;
}
if (m_bInitialized)
{
m_pBufferManager->GetStatus(uSrcStatusCode, pStatusDesc, uSrcPercentDone);
statusCode = uSrcStatusCode;
buffer = uSrcPercentDone;
}
else
{
buffer = 0;
statusCode = HX_STATUS_INITIALIZING;
percentDone = 0;
uStatusCode = statusCode;
pStatusDesc = NULL;
ulPercentDone = buffer;
}
#ifdef _RAHULDEBUG
{
char str[255]; /* Flawfinder: ignore */
::sprintf(str, "GetStatus: BufMgr %u ", buffer); /* Flawfinder: ignore */
OutputDebugString(str);
}
#endif
if (buffer > 100)
buffer = 0;
/* If we have not yet received a single packet, do not claim to
* be done with buffering. This is needed to correctyl playback sparse
* datatypes with no preroll.
*/
if (!m_bReceivedData && buffer == 100)
{
buffer = 99;
}
/* We only aggregate buffering from a lower level if we are in a buffering mode.
* Reason: Once the initial bufering is done, we go in buffering more ONLY IF the
* renderer tells us that it is in a panic state and we run out of packets.
*/
if (buffer == 100 && !m_bInitialBuffering)
{
// Rebuffer requested by the Renderer might not be
// done yet
if (!IsRebufferDone())
{
uStatusCode = HX_STATUS_BUFFERING;
ulPercentDone = 99;
}
else
{
uStatusCode = HX_STATUS_READY;
}
goto cleanup;
}
if (HX_STATUS_CONTACTING == statusCode)
{
uStatusCode = HX_STATUS_CONTACTING;
ulPercentDone = 0;
}
else if (HX_STATUS_READY == statusCode && 100 == buffer)
{
uStatusCode = HX_STATUS_READY;
ulPercentDone = 0;
}
else if (HX_STATUS_INITIALIZING == statusCode || HX_STATUS_INITIALIZING == uStatusCode)
{
uStatusCode = HX_STATUS_BUFFERING;
ulPercentDone = 0;
}
else
{
uStatusCode = HX_STATUS_BUFFERING;
ulPercentDone = buffer;
}
if (uStatusCode == HX_STATUS_BUFFERING && m_uLastBuffering < 100)
{
if (ulPercentDone < m_uLastBuffering)
{
ulPercentDone = m_uLastBuffering;
}
else
{
m_uLastBuffering = ulPercentDone;
}
}
if (m_bInitialBuffering && HX_STATUS_READY == uStatusCode)
{
InitialBufferingDone();
m_uLastBuffering = 100;
}
/* If we had a delayed start, we do not want to show that we are
* in buffering state UNLESS it is really time to give out packets
* and we do not have any.
*/
if (m_bInitialized && m_ulDelay > 0 && m_pPlayer &&
uStatusCode == HX_STATUS_BUFFERING &&
ulPercentDone < 100)
{
UINT32 ulCurrentTime = m_pPlayer->GetInternalCurrentPlayTime();
if ((ulCurrentTime+MIN_BUFFERTIME_BEFORE_DELAY) < m_ulDelay)
{
ulPercentDone = 100;
}
}
cleanup:
if (m_pBufferCtl)
{
if ((HX_STATUS_READY == m_uLastStatusCode) &&
(HX_STATUS_BUFFERING == uStatusCode))
{
UINT32 ulRemainToBufferInMs = 0;
UINT32 ulRemainToBuffer = 0;
if (m_pBufferManager)
{
m_pBufferManager->GetRemainToBuffer(ulRemainToBufferInMs,
ulRemainToBuffer);
}
m_pBufferCtl->OnBuffering(ulRemainToBufferInMs, ulRemainToBuffer);
}
else if ((HX_STATUS_BUFFERING == m_uLastStatusCode) &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -