📄 hxsrc.cpp
字号:
int nStreamCnt = GetNumStreams();
ULONG32 ulIsAudioStream = FALSE;
for (int i=0; i<nStreamCnt && !bAtLeastOneAudioStream; i++)
{
GetStreamHeaderInfo(i, pHeader);
pHeader->GetPropertyULONG32("IsAudioStream", ulIsAudioStream);
if (ulIsAudioStream)
{
bAtLeastOneAudioStream = TRUE;
}
HX_RELEASE(pHeader);
}
}
pAudioPlayer->Release();
return bAtLeastOneAudioStream;
}
void
HXSource::EventReady(CHXEvent* pEvent)
{
if (m_pPlayer)
{
m_pPlayer->EventReady(this, pEvent);
}
}
BOOL
HXSource::IsAudioStreamFromThisSource(IHXValues* pAudioHeader)
{
BOOL bFound = FALSE;
CHXMapLongToObj::Iterator ndxStreamIterator = mStreamInfoTable->Begin();
for (; ndxStreamIterator != mStreamInfoTable->End(); ++ndxStreamIterator)
{
STREAM_INFO* pStreamInfo = (STREAM_INFO*) (*ndxStreamIterator);
if (pStreamInfo->m_pHeader == pAudioHeader)
{
bFound = TRUE;
break;
}
}
return bFound;
}
ULONG32
HXSource::GetAvailableMemory()
{
ULONG32 memAvail = 1000000;
#if defined (__MWERKS__)
// XXX Hack! We can't call any of the Memory Manager calls at interrupt time so we will have
// to change this to ask our interrupt safe memory allocator how much memory is free
memAvail = 1000000;
#elif defined(_WINCE) && !defined(_WIN32_WCE_EMULATION)
STORE_INFORMATION stInfo;
GetStoreInformation(&stInfo);
memAvail = stInfo.dwFreeSize;
#elif (_WIN32)
MEMORYSTATUS status;
status.dwLength = sizeof(MEMORYSTATUS);
GlobalMemoryStatus(&status);
memAvail = status.dwAvailPageFile;
#elif defined( _WINDOWS)
memAvail = GetFreeSpace(0);
#elif defined (_UNIX)
// XXXX Need to get this to compile.
memAvail = 1000000;
#endif
return memAvail;
}
void
HXSource::ReportError(HX_RESULT theErr)
{
if (m_pPlayer)
{
m_pPlayer->ReportError(this, theErr);
}
}
HX_RESULT
HXSource::AdjustClipTime(void)
{
HX_RESULT theErr = HXR_OK;
UINT32 ulOriginalDuration = m_ulDuration;
UINT32 ulTrackEndTime = 0;
CHXMapLongToObj::Iterator i;
BOOL bCustomEndTimeSet = FALSE;
if (m_bPartOfPrefetchGroup)
{
if (m_ulDelay)
{
m_ulPrefetchDelay = m_ulDelay;
m_bDelayed = TRUE;
AdjustClipBandwidthStats(FALSE);
DoPause();
}
m_ulEndTime = 0;
m_bCustomEndTime = FALSE;
goto cleanup;
}
/* For a live stream, the only qualifiers that make sense
* are Duration and Delay. All other qualifiers should be made 0
*/
if (mLiveStream)
{
m_ulStartTime = 0;
if (!m_bRestrictedLiveStream)
{
m_ulEndTime = 0;
}
}
for (i = mStreamInfoTable->Begin(); i != mStreamInfoTable->End(); ++i)
{
STREAM_INFO* pStreamInfo = (STREAM_INFO*) (*i);
ulTrackEndTime = 0;
HX_RESULT hrTemp = pStreamInfo->m_pHeader->GetPropertyULONG32("EndTime", ulTrackEndTime);
if (HXR_OK == hrTemp && !m_bCustomEndTime)
{
if (m_ulEndTime < ulTrackEndTime)
{
m_ulEndTime = ulTrackEndTime;
}
pStreamInfo->m_bCustomEndTime = TRUE;
}
else if (m_bCustomEndTime)
{
ulTrackEndTime = m_ulEndTime;
pStreamInfo->m_bCustomEndTime = TRUE;
}
if (ulTrackEndTime > 0 && !mLiveStream)
{
pStreamInfo->m_pHeader->SetPropertyULONG32("TrackEndTime",
ulTrackEndTime);
bCustomEndTimeSet = TRUE;
}
}
// if max. duration is set on this source
if (m_pSourceInfo &&
m_pSourceInfo->m_ulMaxDuration)
{
if (m_ulRestrictedDuration)
{
if (m_ulRestrictedDuration > m_pSourceInfo->m_ulMaxDuration)
{
m_ulRestrictedDuration = m_pSourceInfo->m_ulMaxDuration;
}
}
else if (m_ulDuration)
{
if (m_ulDuration > m_pSourceInfo->m_ulMaxDuration)
{
m_ulRestrictedDuration = m_pSourceInfo->m_ulMaxDuration;
}
}
}
// By default, we always set the end time to be the duration of the clip,
// but do not set end time if it was manually specified.
if (!bCustomEndTimeSet && !mLiveStream)
{
m_ulEndTime = m_ulDuration;
}
/* Check if there is any end time */
if ((m_ulEndTime < m_ulDuration) || m_bRestrictedLiveStream)
{
m_ulDuration = m_ulEndTime;
}
/* Is "Delay" specified too? */
if (m_ulDelay > 0)
{
/* Increase duration of this clip */
m_ulDuration += m_ulDelay;
UINT32 ulStartTime = 0;
if (m_ulDelay > m_ulPreRollInMs + NETWORK_FUDGE_FACTOR)
{
ulStartTime = m_ulDelay - (m_ulPreRollInMs + NETWORK_FUDGE_FACTOR);
}
// no need to pause delayed persistent component since Pause() will be called
// on actual tracks' AdjustClipTime() if necessary
if (m_pSourceInfo && !m_pSourceInfo->m_bIsPersistentSource)
{
m_bDelayed = TRUE;
AdjustClipBandwidthStats(FALSE);
DoPause();
}
}
if (m_ulStartTime > 0) /* reduce duration by start time amount */
{
if (m_ulDuration > m_ulStartTime)
{
m_ulDuration -= m_ulStartTime;
}
else
{
/* This is bad case. We consider it invalid */
m_ulDuration = 0;
}
}
/* We now allow to increase the default duration of the clip */
if (m_ulRestrictedDuration > 0)
{
m_ulDuration = m_ulRestrictedDuration + m_ulDelay;
if (mLiveStream && !m_bRestrictedLiveStream)
{
m_bRestrictedLiveStream = TRUE;
m_ulEndTime = m_ulRestrictedDuration + m_ulStartTime;
}
if (m_ulEndTime > m_ulRestrictedDuration + m_ulStartTime)
{
m_ulEndTime = m_ulRestrictedDuration + m_ulStartTime;
}
}
// orig duration is active duration for this source -- time for which
// this source lasts.
if (m_ulDuration > m_ulDelay)
{
m_ulOriginalDuration = m_ulDuration - m_ulDelay;
}
else
{
m_ulOriginalDuration = 0;
}
if (m_pURL &&
rtspProtocol == m_pURL->GetProtocol() &&
m_llLastExpectedPacketTime != m_ulEndTime &&
!m_bFirstResume)
{
m_bRTSPRuleFlagWorkAround = TRUE;
}
/* If we receive a packet after this stream, we consider the stream to be done */
m_llLastExpectedPacketTime = CAST_TO_INT64 m_ulEndTime;
// Seek to the starting position only if the source
// has not been resumed yet
if (m_ulStartTime > 0 && m_bFirstResume)
{
/* We will add m_ulStartTime in DoSeek() call*/
theErr = DoSeek(0);
}
/* Update stream durations if required */
for (i = mStreamInfoTable->Begin(); i != mStreamInfoTable->End(); ++i)
{
STREAM_INFO* pStreamInfo = (STREAM_INFO*) (*i);
if (m_ulStartTime > 0)
{
pStreamInfo->m_pHeader->SetPropertyULONG32("TrackStartTime",
m_ulStartTime);
}
if (m_ulEndTime > 0 &&
!mLiveStream &&
HXR_OK != pStreamInfo->m_pHeader->GetPropertyULONG32("TrackEndTime",
ulTrackEndTime))
{
pStreamInfo->m_pHeader->SetPropertyULONG32("TrackEndTime",
m_ulEndTime);
}
if (ulOriginalDuration != m_ulDuration)
{
pStreamInfo->m_ulDuration = m_ulDuration;
pStreamInfo->m_pHeader->SetPropertyULONG32("Duration",
pStreamInfo->m_ulDuration);
}
if (m_ulDelay > 0)
{
pStreamInfo->m_pHeader->SetPropertyULONG32("Delay", m_ulDelay);
}
}
//{FILE* f1 = ::fopen("d:\\temp\\url.txt", "a+"); ::fprintf(f1, "%p %s %lu %lu\n", this, m_pszURL, m_ulDelay, m_ulDuration);::fclose(f1);}
cleanup:
m_bClipTimeAdjusted = TRUE;
return theErr;
}
void
HXSource::GenerateFakeLostPacket(CHXEvent*& theEvent)
{
IHXPacket* pPacket = theEvent->GetPacket();
CHXPacket* pLostPacket = new CHXPacket;
pLostPacket->AddRef();
pLostPacket->Set(0, 0, pPacket->GetStreamNumber(), 0, 0);
pLostPacket->SetAsLost();
/* Create a new event with lost packet */
CHXEvent* pEvent = new CHXEvent(pLostPacket);
pEvent->SetTimeStartPos(theEvent->GetTimeStartPos());
pEvent->SetTimeOffset(theEvent->GetTimeOffset());
pEvent->SetPreSeekEvent(theEvent->IsPreSeekEvent());
pLostPacket->Release();
delete theEvent;
theEvent = pEvent;
}
char*
HXSource::GetAltURL(BOOL& bDefault)
{
#if defined(HELIX_FEATURE_ALT_URL)
char* pAltURL = NULL;
if (!m_pURL || m_bInitialized)
{
goto cleanup;
}
pAltURL = m_pURL->GetAltURL(bDefault);
cleanup:
return pAltURL;
#else
return NULL;
#endif /* HELIX_FEATURE_ALT_URL */
}
HX_RESULT
HXSource::SetRequest(const CHXURL* pURL, BOOL bAltURL)
{
HX_RESULT hr = HXR_OK;
IHXValues* pValues = NULL;
IHXValues* pValuesInRequest = NULL;
IHXGroup* pGroup = NULL;
IHXGroup2* pGroup2 = NULL;
IHXGroupManager* pGroupManager = NULL;
HX_RELEASE(m_pRequest);
if (m_pPlayer)
{
m_pPlayer->GetActiveRequest(m_pRequest);
if (m_pRequest)
{
m_pPlayer->ResetActiveRequest();
}
}
#if defined(HELIX_FEATURE_ADVANCEDGROUPMGR)
if (m_pPlayer && m_pSourceInfo)
{
if (HXR_OK == m_pPlayer->QueryInterface(IID_IHXGroupManager, (void**)&pGroupManager))
{
if (HXR_OK == pGroupManager->GetGroup(m_pSourceInfo->m_uGroupID, pGroup))
{
if (HXR_OK == pGroup->QueryInterface(IID_IHXGroup2, (void**)&pGroup2))
{
pGroup2->GetTrack2(m_pSourceInfo->m_uTrackID, pValues, pValuesInRequest);
UINT32 ulValue = 0;
char szDuration[128] = {0}; /* Flawfinder: ignore */
IHXBuffer* pBuffer = NULL;
if (pValues && HXR_OK == pValues->GetPropertyULONG32("Duration", ulValue))
{
if (!pValuesInRequest)
{
pValuesInRequest = new CHXHeader();
if( pValuesInRequest )
{
pValuesInRequest->AddRef();
}
else
{
hr = HXR_OUTOFMEMORY;
}
}
if (pValuesInRequest)
{
SafeSprintf (szDuration, 128, "%lu", ulValue); /* Flawfinder: ignore */
pBuffer = new CHXBuffer();
pBuffer->AddRef();
pBuffer->Set((UCHAR*)szDuration, strlen(szDuration) + 1);
pValuesInRequest->SetPropertyCString("Duration", pBuffer);
HX_RELEASE(pBuffer);
}
}
}
HX_RELEASE(pGroup2);
}
HX_RELEASE(pGroup);
}
HX_RELEASE(pGroupManager);
}
#endif /* HELIX_FEATURE_ADVANCEDGROUPMGR */
IHXRegistry* pRegistry = NULL;
m_pEngine->QueryInterface(IID_IHXRegistry, (void**)&pRegistry);
hr = ::SetRequest(pURL->GetEscapedURL(), bAltURL, m_pPreferences, pRegistry, pValuesInRequest, m_pRequest);
HX_RELEASE(pValues);
HX_RELEASE(pValuesInRequest);
HX_RELEASE(pRegistry);
#if defined(HELIX_FEATURE_RECORDCONTROL)
if(hr == HXR_OK && pURL->GetProtocol() != fileProtocol)
{
if(!m_pRecordControl)
{
m_pRecordControl = new HXRecordControl((IHXPlayer*)m_pPlayer, (IHXStreamSource*)this);
if(m_pRecordControl)
{
m_pRecordControl->AddRef();
if(m_pRecordControl->IsValid())
m_bPlayFromRecordControl = m_pRecordControl->CanGetPackets();
else
HX_RELEASE(m_pRecordControl);
}
}
if(m_pRecordControl)
{
m_pRecordControl->SetSource((IHXStreamSource*)this);
}
}
#endif /* HELIX_FEATURE_RECORDCONTROL */
return hr;
}
void
HXSource::UpdateDuration(UINT32 ulDuration)
{
CHXSimpleList* pRepeatList = m_pSourceInfo->GetRepeatList();
// ulDuration excludes the delay time
if (pRepeatList &&
ulDuration >= (m_ulDuration - m_ulDelay))
{
m_pSourceInfo->m_ulTotalTrackDuration = ulDuration + m_ulDelay;
if (m_pSourceInfo->m_pPeerSourceInfo)
{
m_pSourceInfo->m_pPeerSourceInfo->m_ulTotalTrackDuration = m_pSourceInfo->m_ulTotalTrackDuration;
}
}
else
{
m_ulOriginalDuration = m_ulRestrictedDuration = ulDuration;
AdjustClipTime();
m_pSourceInfo->UpdateDuration(m_ulDuration);
}
}
void
HXSource::UpdateDelay(UINT32 ulDelay)
{
m_ulDelay = ulDelay;
AdjustClipTime();
m_pSourceInfo->UpdateDelay(m_ulDelay);
}
void
HXSource::InitialBufferingDone(void)
{
m_bInitialBuffering = FALSE;
// resume if we satisfy the initial preroll AND we have issued
// rebuffer
// note: IsRebufferRequired() should return FALSE!!
if (m_bRebufferingRequired)
{
m_bRebufferingRequired = IsRebufferRequired();
HX_ASSERT(!m_bRebufferingRequired);
}
return;
}
void
HXSource::DoRebuffer(void)
{
m_bRebufferingRequired = TRUE;
if (m_pPlayer)
{
m_pPlayer->InternalPause();
ReBuffer();
}
return;
}
BOOL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -