buffmgr.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:20k
- /* ***** 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 "hlxclib/stdio.h"
- #include "hxcom.h"
- #include "hxcomm.h"
- #include "ihxpckts.h"
- #include "hxslist.h"
- #include "hxtick.h"
- #include "hxcore.h"
- #include "chxeven.h"
- #include "hxbsrc.h"
- #include "hxsrc.h"
- #include "hxntsrc.h"
- #include "hxstrm.h"
- #include "strminfo.h"
- #include "buffmgr.h"
- #include "hxsmbw.h"
- #include "hxgroup.h"
- #include "hxplay.h"
- #include "errdbg.h"
- #include "hxheap.h"
- #ifdef _DEBUG
- #undef HX_THIS_FILE
- static const char HX_THIS_FILE[] = __FILE__;
- #endif
- #if defined(__TCS__)
- #define MAX_ADDITIONAL_BUFFERING 3000
- #else
- #define MAX_ADDITIONAL_BUFFERING 10000
- #endif /* __TCS__ */
- CBufferManager::CBufferManager(HXSource* pParent)
- {
- m_ulMaxAdditionalBufferingInMs = MAX_ADDITIONAL_BUFFERING;
- m_llHighestTimeStamp = 0;
- m_ulTotalPauseTime = 0;
- m_ulLastPauseTime = 0;
- m_ulAdditionalBufferingInMs = 0;
- m_bBufferStartTimeToBeSet = TRUE;
- m_ulMinimumInitialAudioPreroll = 0;
- m_ulMinimumSourcePreroll = 0;
- m_bPerfectPlay = FALSE;
- m_bPaused = FALSE;
- m_state = BUFFMGR_READY;
- m_pParent = pParent;
- m_pParent->AddRef();
- m_bLocalPlayback = pParent->IsLocalSource();
- m_pStreamInfoTable = pParent->GetStreamInfoTable();
- m_bFirstResumeDone = FALSE;
- m_bIsSeekPerformed = FALSE;
- m_bBufferedPlay = FALSE;
- m_bBufferCalcToBeChanged = FALSE;
- m_bIsInitialized = FALSE;
- m_ulSeekTime = 0;
- }
- CBufferManager::~CBufferManager()
- {
- HX_RELEASE(m_pParent);
- }
- HX_RESULT
- CBufferManager::Init()
- {
- UINT32 ulPerfectPlayTime = 0;
- UINT32 ulMinimumPreroll = 0;
- STREAM_INFO* pStreamInfo = NULL;
- CHXMapLongToObj::Iterator i;
- // There is no buffered or perfect play with MIN_HEAP on.
- #if !defined(HELIX_CONFIG_MIN_PCM_PUSHDOWN_BYTES)
- SetPerfectPlay(m_pParent->IsPerfectPlay());
- if (m_bPerfectPlay || m_bBufferedPlay)
- {
- // caculate how much extra preroll for the perfect play
- ulPerfectPlayTime = m_pParent->GetPerfectPlayTime();
- }
- #endif
- // ajust buffering information of each stream
- for (i = m_pStreamInfoTable->Begin(); i != m_pStreamInfoTable->End(); ++i)
- {
- pStreamInfo = (STREAM_INFO*) (*i);
- pStreamInfo->BufferingState().Init(ulPerfectPlayTime);
- HX_ASSERT(pStreamInfo->m_EventList.GetHeadPosition() == NULL);
- }
- m_bIsInitialized = TRUE;
- /* Was there a Seek called before Initialization... may happen for a clip
- * with Start time
- */
- if (m_bIsSeekPerformed)
- {
- DoSeek(m_ulSeekTime);
- }
- return HXR_OK;
- }
- HX_RESULT
- CBufferManager::SetMinimumPreroll(BOOL bPerfectPlay, UINT32 ulSourcePreroll,
- UINT32 ulInitialAudioPreroll,
- BOOL bModifyStartTime /* = TRUE */)
- {
- m_ulMinimumInitialAudioPreroll = ulInitialAudioPreroll;
- m_ulMinimumSourcePreroll = ulSourcePreroll;
- SetPerfectPlay(bPerfectPlay);
- UpdateMinimumPreroll(bModifyStartTime);
- return HXR_OK;
- }
- void
- CBufferManager::UpdateMinimumPreroll(BOOL bModifyStartTime)
- {
- UINT32 ulMinimumPreroll = 0;
- UINT32 ulPerfectPlayTime = 0;
- UINT32 ulStartTime = 0;
- UINT32 ulEventStartTime = 0;
- UINT32 ulPacketTime = 0;
- STREAM_INFO* pStreamInfo = NULL;
- BOOL bPreDataToBeCalculated = FALSE;
- CHXMapLongToObj::Iterator i;
- // There is no buffered or perfect play with MIN_HEAP on.
- #if !defined(HELIX_CONFIG_MIN_PCM_PUSHDOWN_BYTES)
- if (m_bPerfectPlay || m_bBufferedPlay)
- {
- m_ulMaxAdditionalBufferingInMs = 0;
- // caculate how much extra preroll for the perfect play
- ulPerfectPlayTime = m_pParent->GetPerfectPlayTime();
- }
- else
- {
- m_ulMaxAdditionalBufferingInMs = MAX_ADDITIONAL_BUFFERING;
- if (m_ulAdditionalBufferingInMs > m_ulMaxAdditionalBufferingInMs)
- {
- m_ulAdditionalBufferingInMs = m_ulMaxAdditionalBufferingInMs;
- }
- ulPerfectPlayTime = m_ulAdditionalBufferingInMs;
- }
- #endif
- ulStartTime = m_pParent->GetStartTime();
- // adjust buffering information of each stream
- for (i = m_pStreamInfoTable->Begin(); i != m_pStreamInfoTable->End(); ++i)
- {
- pStreamInfo = (STREAM_INFO*) (*i);
-
- pStreamInfo->BufferingState().SetMinimumPreroll(
- m_ulMinimumSourcePreroll,
- m_ulMinimumInitialAudioPreroll,
- ulPerfectPlayTime,
- (m_state == BUFFMGR_REBUFFER));
- if (bModifyStartTime)
- {
- pStreamInfo->UpdateStartTimes(ulStartTime);
- }
- }
- m_bBufferCalcToBeChanged = FALSE;
- }
- HX_RESULT
- CBufferManager::Stop(void)
- {
- STREAM_INFO* pStreamInfo = NULL;
- CHXMapLongToObj::Iterator i;
- // stop buffering of each stream
- for (i = m_pStreamInfoTable->Begin(); i != m_pStreamInfoTable->End(); ++i)
- {
- pStreamInfo = (STREAM_INFO*) (*i);
-
- pStreamInfo->BufferingState().Stop();
- // DEBUG_OUT(m_pParent->m_pPlayer, (s,
- // "BufferManager::Stop %p", pStreamInfo));
- }
- return HXR_OK;
- }
- HX_RESULT
- CBufferManager::DoSeek(UINT32 ulSeekTime, BOOL bSeekInsideRecordBuffer)
- {
- m_state = BUFFMGR_SEEK;
- m_bIsSeekPerformed = TRUE;
- m_ulSeekTime = ulSeekTime;
- /* We will call Reset during Init() call */
- if (!m_bIsInitialized)
- {
- return HXR_OK;
- }
- // reset all the preroll attributes
- Reset(ulSeekTime, bSeekInsideRecordBuffer);
- return HXR_OK;
- }
- HX_RESULT
- CBufferManager::DoPause(void)
- {
- m_bPaused = TRUE;
- m_ulLastPauseTime = HX_GET_TICKCOUNT();
- return HXR_OK;
- }
- HX_RESULT
- CBufferManager::DoResume(void)
- {
- if (m_bPaused && m_state != BUFFMGR_SEEK && !m_bBufferStartTimeToBeSet)
- {
- m_ulTotalPauseTime += CALCULATE_ELAPSED_TICKS(m_ulLastPauseTime, HX_GET_TICKCOUNT());
- }
- m_bPaused = FALSE;
- if (!m_bFirstResumeDone)
- {
- m_bFirstResumeDone = TRUE;
- UpdateMinimumPreroll(FALSE);
- }
- return HXR_OK;
- }
- HX_RESULT
- CBufferManager::ReBuffer(void)
- {
- // recaculate only if it is out of the buffering stage
- // and not in perfect play mode
- m_state = BUFFMGR_REBUFFER;
-
- /* go back in buffering mode...
- * each time we come in buffering state, increase the
- * number of packets we buffer by 1 second worth
- * to a max of m_ulMaxAdditionalBuffering secs.
- */
- #ifndef HELIX_CONFIG_MIN_PCM_PUSHDOWN_BYTES
- // increase by 1 sec
- m_ulAdditionalBufferingInMs += 1000;
- if (m_pParent->IsLive())
- {
- m_bPerfectPlay = FALSE;
- m_bBufferedPlay = FALSE;
- }
- #endif // HELIX_CONFIG_MIN_PCM_PUSHDOWN_BYTES
- UpdateMinimumPreroll(FALSE);
- return HXR_OK;
- }
- HX_RESULT
- CBufferManager::Reset(UINT32 ulSeekTime, BOOL bSeekInsideRecordBuffer)
- {
- STREAM_INFO* pStreamInfo = NULL;
- CHXEventList* pEventList = NULL;
- CHXEvent* pEvent = NULL;
- CHXMapLongToObj::Iterator i;
- if (m_bBufferCalcToBeChanged)
- {
- UpdateMinimumPreroll(FALSE);
- }
- m_ulBufferingStartTime = 0;
- // reset each stream
- for (i = m_pStreamInfoTable->Begin(); i != m_pStreamInfoTable->End(); ++i)
- {
- pStreamInfo = (STREAM_INFO*) (*i);
-
- // reset
- if (!bSeekInsideRecordBuffer)
- {
- pStreamInfo->m_bSrcStreamDone = FALSE;
- pStreamInfo->m_bPacketRequested = FALSE;
- }
- pStreamInfo->m_bSrcStreamFillingDone = FALSE;
- // Reset buffering state
- pStreamInfo->BufferingState().Reset((m_state == BUFFMGR_SEEK),
- ulSeekTime);
-
- HX_ASSERT(m_state == BUFFMGR_SEEK);
- if (m_state == BUFFMGR_SEEK)
- {
- // remove all pending packets
- pEventList = &pStreamInfo->m_EventList;
- while (pEventList->GetNumEvents() > 0)
- {
- pEvent = pEventList->RemoveHead();
- // Mark it as a pre-seek event and send it to the player
- pEvent->SetPreSeekEvent();
- m_pParent->EventReady(pEvent);
- }
- }
- }
- m_llHighestTimeStamp = 0;
- m_ulTotalPauseTime = 0;
- m_bBufferStartTimeToBeSet = TRUE;
- return HXR_OK;
- }
-
- HX_RESULT
- CBufferManager::UpdateCounters(IHXPacket* pPacket)
- {
- HX_RESULT hr = HXR_OK;
- UINT32 ulStreamNum = 0;
- UINT32 ulBufferSize = 0;
- UINT32 ulBufferTime = 0;
- UINT32 ulElapsedTime = 0;
- INT64 llActualTimeStamp = 0;
- IHXBuffer* pBuffer = NULL;
- STREAM_INFO* pStreamInfo = NULL;
- STREAM_INFO* pThisStreamInfo = NULL;
- UINT32 ulCurrentTime = HX_GET_TICKCOUNT();
- CHXMapLongToObj::Iterator i;
-
- if (!pPacket)
- {
- return HXR_INVALID_PARAMETER;
- }
- if (pPacket->IsLost() &&
- !(pPacket->GetASMFlags() & HX_ASM_DROPPED_PKT))
- {
- // Ignore all lost packets that aren't dropped packets
- return hr;
- }
- ulStreamNum = pPacket->GetStreamNumber();
- if (!m_pStreamInfoTable->Lookup(ulStreamNum, (void*&)pStreamInfo))
- {
- return HXR_INVALID_PARAMETER;
- }
- pThisStreamInfo = pStreamInfo;
- pBuffer = pPacket->GetBuffer();
- if (pBuffer)
- {
- ulBufferSize = pBuffer->GetSize();
- }
- HX_RELEASE(pBuffer);
- ulBufferTime = pPacket->GetTime();
- /* Set Buffering start time for all streams */
- if (m_bBufferStartTimeToBeSet)
- {
- m_bBufferStartTimeToBeSet = FALSE;
- m_ulBufferingStartTime = ulCurrentTime;
- }
- ulElapsedTime = GetElapsedTime(ulCurrentTime);
- BOOL bIsBufferedPlayMode = (m_bPerfectPlay || m_bBufferedPlay ||
- (m_bLocalPlayback && !m_pParent->IsLive()));
- pStreamInfo->BufferingState().OnPacket(ulBufferTime, ulBufferSize,
- ulElapsedTime,
- m_pParent->IsLive(),
- bIsBufferedPlayMode);
- llActualTimeStamp =
- pStreamInfo->BufferingState().CreateINT64Timestamp(ulBufferTime);
-
- // time based preroll by default
- UpdateHighestTimestamps(llActualTimeStamp, pStreamInfo);
- INT64 llLowRefTS = pThisStreamInfo->BufferingState().LowTS();
- // adjust each stream preroll based on the hightest time stamp
- for (i = m_pStreamInfoTable->Begin(); i != m_pStreamInfoTable->End(); ++i)
- {
- pStreamInfo = (STREAM_INFO*) (*i);
-
- BOOL bIsTimestampDelivery = FALSE;
- if (pStreamInfo->m_pStream &&
- pStreamInfo->m_pStream->IsTimeStampDelivery())
- {
- bIsTimestampDelivery = TRUE;
- }
-
- pStreamInfo->BufferingState().UpdateBufferingInMs(llLowRefTS,
- m_llHighestTimeStamp,
- bIsBufferedPlayMode,
- bIsTimestampDelivery,
- ulElapsedTime);
- }
- return hr;
- }
- HX_RESULT
- CBufferManager::GetStatus(REF(UINT16) uStatusCode,
- REF(IHXBuffer*) pStatusDesc,
- REF(UINT16) uPercentDone)
- {
- STREAM_INFO* pStreamInfo = NULL;
- CHXMapLongToObj::Iterator i;
- uStatusCode = HX_STATUS_READY;
- pStatusDesc = NULL;
- uPercentDone = 0;
- // collect from each streams
- for (i = m_pStreamInfoTable->Begin(); i != m_pStreamInfoTable->End(); ++i)
- {
- pStreamInfo = (STREAM_INFO*) (*i);
- uPercentDone += pStreamInfo->BufferingState().GetPercentDone(m_bIsSeekPerformed);
- }
- // average them
- uPercentDone = uPercentDone / m_pStreamInfoTable->GetCount();
- if (uPercentDone >= 100)
- {
- uPercentDone = 100;
- m_state = BUFFMGR_READY;
- }
- else
- {
- uStatusCode = HX_STATUS_BUFFERING;
- }
- // DEBUG_OUT(m_pParent->m_pPlayer, DOL_GENERIC, (s,
- // "BuffMgr::GetStatus: %p Status: %s uPercentDone: %lu ", this,
- // (uStatusCode == HX_STATUS_BUFFERING ? "HX_STATUS_BUFFERING" : "HX_STATUS_READY" ),
- // uPercentDone));
- return HXR_OK;
- }
- HX_RESULT
- CBufferManager::GetRemainToBuffer(REF(UINT32) ulRemainToBufferInMs,
- REF(UINT32) ulRemainToBuffer)
- {
- STREAM_INFO* pStreamInfo = NULL;
-
- ulRemainToBufferInMs = 0;
- ulRemainToBuffer = 0;
- CHXMapLongToObj::Iterator i;
- // caculate each stream
- for (i = m_pStreamInfoTable->Begin(); i != m_pStreamInfoTable->End(); ++i)
- {
- pStreamInfo = (STREAM_INFO*) (*i);
- BOOL bHasPreroll =
- pStreamInfo->BufferingState().HasPreroll(m_bIsSeekPerformed);
- BOOL bHasPredata =
- pStreamInfo->BufferingState().HasPredata(m_bIsSeekPerformed);
-
- UINT32 ulRemainInMs;
- UINT32 ulRemain;
- pStreamInfo->BufferingState().GetRemainToBuffer(ulRemainInMs,
- ulRemain);
- // satisfy the preroll (by default + pre-set)
- if ((!bHasPredata || bHasPreroll) &&
- (ulRemainToBufferInMs < ulRemainInMs))
- {
- ulRemainToBufferInMs = ulRemainInMs;
- }
-
- // satisfy the predata
- if (bHasPredata)
- {
- ulRemainToBuffer += ulRemain;
- }
- }
- return HXR_OK;
- }
- HX_RESULT
- CBufferManager::GetMaximumPreroll(REF(UINT32) ulMaximumPrerollInMs)
- {
- STREAM_INFO* pStreamInfo = NULL;
- CHXMapLongToObj::Iterator i;
- ulMaximumPrerollInMs = 0;
- // get max. preroll among the streams
- for (i = m_pStreamInfoTable->Begin(); i != m_pStreamInfoTable->End(); ++i)
- {
- pStreamInfo = (STREAM_INFO*) (*i);
-
- UINT32 ulMinPrerollInMs =
- pStreamInfo->BufferingState().GetMinPrerollInMs();
- if (ulMaximumPrerollInMs < ulMinPrerollInMs)
- {
- ulMaximumPrerollInMs = ulMinPrerollInMs;
- }
- }
-
- return HXR_OK;
- }
- HX_RESULT
- CBufferManager::GetExcessBufferInfo(REF(UINT32) ulRemainToBufferInMs,
- REF(UINT32) ulRemainToBuffer,
- REF(UINT32) ulExcessBufferInMs,
- REF(UINT32) ulExcessBuffer,
- REF(BOOL) bValidInfo,
- REF(UINT32) ulActualExcessBufferInMs,
- REF(UINT32) ulActualExcessBuffer)
- {
- STREAM_INFO* pStreamInfo = NULL;
- INT64 llTheLowestTS = 0;
- INT64 llTheHighestTS = 0;
- BOOL bIsFirst = TRUE;
- STREAM_INFO* pNonEmptyStreamInfo = NULL;
-
- ulRemainToBufferInMs = 0;
- ulRemainToBuffer = 0;
- ulExcessBufferInMs = 0;
- ulExcessBuffer = 0;
- bValidInfo = FALSE;
- ulActualExcessBufferInMs= 0;
- ulActualExcessBuffer = 0;
- CHXMapLongToObj::Iterator i;
- /*
- * - Update transport stats for each stream.
- * - Find the lowest and highest timestamps across all streams
- * - Keep track of the stream with the lowest timestamp and is
- * buffering data
- */
- for (i = m_pStreamInfoTable->Begin(); i != m_pStreamInfoTable->End(); ++i)
- {
- pStreamInfo = (STREAM_INFO*) (*i);
- INT64 llLowestTimestampAtTransport = 0;
- INT64 llHighestTimestampAtTransport = 0;
- ULONG32 ulNumBytesAtTransport = 0;
- BOOL bDoneAtTransport = FALSE;
- m_pParent->GetCurrentBuffering(pStreamInfo->m_uStreamNumber,
- llLowestTimestampAtTransport,
- llHighestTimestampAtTransport,
- ulNumBytesAtTransport,
- bDoneAtTransport);
- pStreamInfo->BufferingState().UpdateTransportStats(
- llLowestTimestampAtTransport,
- llHighestTimestampAtTransport,
- ulNumBytesAtTransport,
- bDoneAtTransport);
- if (ulNumBytesAtTransport > 0)
- {
- if (bIsFirst)
- {
- bIsFirst = FALSE;
- llTheLowestTS = llLowestTimestampAtTransport;
- llTheHighestTS = llHighestTimestampAtTransport;
- pNonEmptyStreamInfo = pStreamInfo;
- }
- else
- {
- if (llTheLowestTS > llLowestTimestampAtTransport)
- {
- llTheLowestTS = llLowestTimestampAtTransport;
- /* This is the stream with the lowest timestamp */
- pNonEmptyStreamInfo = pStreamInfo;
- }
- if (llTheHighestTS < llHighestTimestampAtTransport)
- {
- llTheHighestTS = llHighestTimestampAtTransport;
- }
- }
- }
- }
- /* If none of the streams have any data buffered at the transport layer,
- * return.
- */
- if (!pNonEmptyStreamInfo)
- {
- return HXR_OK;
- }
- for (i = m_pStreamInfoTable->Begin(); i != m_pStreamInfoTable->End(); ++i)
- {
- pStreamInfo = (STREAM_INFO*) (*i);
- UINT32 ulExcessForThisStreamInMs = 0;
- UINT32 ulExcessForThisStream = 0;
- pStreamInfo->BufferingState().GetExcessBufferInfo(llTheLowestTS,
- llTheHighestTS,
- m_bIsSeekPerformed,
- ulRemainToBufferInMs,
- ulRemainToBuffer,
- ulExcessBufferInMs,
- ulExcessBuffer,
- ulExcessForThisStreamInMs,
- ulExcessForThisStream);
- /* Update Actual Values Regardless of Preroll / PreData */
- ulActualExcessBuffer += ulExcessForThisStream;
- if (ulActualExcessBufferInMs < ulExcessForThisStreamInMs)
- {
- ulActualExcessBufferInMs = ulExcessForThisStreamInMs;
- }
- }
- bValidInfo = TRUE;
- if (ulRemainToBufferInMs >= ulExcessBufferInMs)
- {
- ulRemainToBufferInMs -= ulExcessBufferInMs;
- ulExcessBufferInMs = 0;
- }
- else
- {
- ulExcessBufferInMs -= ulRemainToBufferInMs;
- ulRemainToBufferInMs = 0;
- }
- if (ulRemainToBuffer > 0)
- {
- ulExcessBuffer = 0;
- }
- return HXR_OK;
- }
- void
- CBufferManager::EnterBufferedPlay(void)
- {
- #if !defined(HELIX_CONFIG_MIN_PCM_PUSHDOWN_BYTES)
- if (!m_bBufferedPlay && !m_bPerfectPlay)
- {
- m_bBufferedPlay = TRUE;
- UINT32 ulRemainToBufferInMs = 0;
- UINT32 ulRemainToBuffer = 0;
-
- GetRemainToBuffer(ulRemainToBufferInMs, ulRemainToBuffer);
-
- /* If we are not done with buffering yet, update the buffering
- * calc now!
- */
- if (ulRemainToBufferInMs > 0 ||
- ulRemainToBuffer > 0)
- {
- UpdateMinimumPreroll(FALSE);
- }
- else
- {
- m_bBufferCalcToBeChanged = TRUE;
- }
- }
- #endif // (HELIX_CONFIG_MIN_PCM_PUSHDOWN_BYTES)
- }
- void
- CBufferManager::LeaveBufferedPlay(void)
- {
- #if !defined(HELIX_CONFIG_MIN_PCM_PUSHDOWN_BYTES)
- if (m_bBufferedPlay)
- {
- m_bBufferCalcToBeChanged = TRUE;
- m_bBufferedPlay = FALSE;
- }
- #endif // (HELIX_CONFIG_MIN_PCM_PUSHDOWN_BYTES)
- }
- UINT32 CBufferManager::GetElapsedTime(UINT32 ulCurrentTime)
- {
- UINT32 ulElapsedTime =
- CALCULATE_ELAPSED_TICKS(m_ulBufferingStartTime, ulCurrentTime);
-
- if (m_ulTotalPauseTime > 0)
- {
- HX_ASSERT(ulElapsedTime >= m_ulTotalPauseTime);
- ulElapsedTime = ulElapsedTime > m_ulTotalPauseTime ?
- ulElapsedTime - m_ulTotalPauseTime : 0;
- }
- return ulElapsedTime;
- }
- void CBufferManager::UpdateHighestTimestamps(INT64 llActualTimeStamp,
- STREAM_INFO* pStreamInfo)
- {
- // we apply the highest packet time-stamp to every stream
- // to solve infinite buffering
- if (m_llHighestTimeStamp < llActualTimeStamp)
- {
- m_llHighestTimeStamp = llActualTimeStamp;
- }
- }
- void CBufferManager::SetPerfectPlay(BOOL bPerfectPlay)
- {
- m_bPerfectPlay = bPerfectPlay;
- if (m_pParent->IsLive())
- {
- m_bPerfectPlay = FALSE;
- m_bBufferedPlay = FALSE;
- }
- }