📄 hxsrc.cpp
字号:
return pStreamInfo->m_pHeader;
}
else
{
return NULL;
}
}
HX_RESULT
HXSource::GetStreamHeaderInfo(UINT16 index, IHXValues*& hdr)
{
HX_TRACE("HXSource::GetStreamHeaderInfo");
// sanity check
if (index >= m_uNumStreams)
{
return HXR_INVALID_PARAMETER; // HX_INVALID_INDEX;
}
CHXMapLongToObj::Iterator i = mStreamInfoTable->Begin();
for (UINT16 j=0; j < index; j++)
{
++i;
}
STREAM_INFO* pStreamInfo = (STREAM_INFO*) *i;
hdr = pStreamInfo->m_pHeader;
if (hdr)
{
hdr->AddRef();
}
return HXR_OK;
}
void HXSource::SetFlags(UINT16 flags)
{
mFlags = flags;
if (mFlags & HX_PERFECT_PLAY_ENABLED)
{
m_bPerfectPlayAllowed = TRUE;
}
else
{
m_bPerfectPlayAllowed = FALSE;
}
if (mFlags & HX_SAVE_ENABLED)
{
mSaveAsAllowed = TRUE;
}
else
{
mSaveAsAllowed = FALSE;
}
}
#if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
HX_RESULT HXSource::CopyMetaDataToRegistry(IHXValues* pHeader)
{
// get Request Object
char pszServerMetaData[256] = {0}; /* Flawfinder: ignore */
char pszMetaData[256] = {0}; /* Flawfinder: ignore */
IHXValues* pReqHeaders = NULL;
IHXRequest* pRequest = NULL;
IHXBuffer* pBuffer = NULL;
char szRegKeyName[MAX_DISPLAY_NAME] = {0}; /* Flawfinder: ignore */
char buff[MAX_DISPLAY_NAME] = {0}; /* Flawfinder: ignore */
char szSMDKey[256]; /* Flawfinder: ignore */
ULONG32 ulValue = 0;
IHXBuffer* pParentName = NULL;
UINT32 regid = 0;
const char szServerMetaData[] = {"ServerMetaData"};
if (HXR_OK == m_pRegistry->GetPropName(m_pStats->m_ulRegistryID, pParentName))
{
SafeStrCpy(buff, (const char*) pParentName->GetBuffer(), MAX_DISPLAY_NAME);
char* pDot = strrchr(buff, '.');
if (pDot)
{
*pDot = '\0';
}
SafeStrCpy(szSMDKey, buff, 256);
if (HXR_OK == GetRequest(pRequest))
{
// get request headers
if (HXR_OK == pRequest->GetRequestHeaders(pReqHeaders))
{
// look for the meta data properties
if (HXR_OK == pReqHeaders->GetPropertyCString("AcceptMetaInfo", pBuffer))
{
SafeStrCpy(pszMetaData, (char*) pBuffer->GetBuffer(), 256);
HX_RELEASE(pBuffer);
// look for comma delimited entries
const char* pCharEntryStart = pszMetaData;
const char* pCharEntryEnd = pCharEntryStart;
while (pCharEntryEnd && *pCharEntryEnd)
{
++pCharEntryEnd;
if (*pCharEntryEnd == ',' || !*pCharEntryEnd)
{
// copy next prop request into buffer
strncpy(buff, pCharEntryStart, (UINT32)pCharEntryEnd - (UINT32)pCharEntryStart); /* Flawfinder: ignore */
*(buff+(UINT32)pCharEntryEnd - (UINT32)pCharEntryStart) = '\0';
// see if this prop is in file header (it should be!)
if (HXR_OK == pHeader->GetPropertyCString(buff, pBuffer))
{
// create new registry entry
SafeSprintf(szRegKeyName, MAX_DISPLAY_NAME, "%s.%s", pParentName->GetBuffer(), buff);
regid = m_pRegistry->GetId(szRegKeyName);
if (!regid)
{
m_pRegistry->AddStr(szRegKeyName, pBuffer);
}
else
{
// set new value
m_pRegistry->SetStrByName(szRegKeyName, pBuffer);
}
HX_RELEASE(pBuffer);
}
else if (HXR_OK == pHeader->GetPropertyULONG32(buff, ulValue))
{
// create new registry entry
SafeSprintf(szRegKeyName, MAX_DISPLAY_NAME, "%s.%s", pParentName->GetBuffer(), buff);
regid = m_pRegistry->GetId(szRegKeyName);
if (!regid)
{
m_pRegistry->AddInt(szRegKeyName, ulValue);
}
else
{
// set new value
m_pRegistry->SetIntByName(szRegKeyName, ulValue);
}
}
pCharEntryStart = pCharEntryEnd + 1;
}
}
}
// look for the meta data properties
if (HXR_OK == pReqHeaders->GetPropertyCString("AcceptServerMetaData", pBuffer))
{
SafeStrCpy(pszServerMetaData, (char*) pBuffer->GetBuffer(), 256);
HX_RELEASE(pBuffer);
// first make sure we have a composit key for "statistics.Player0.ServerMetaData"
SafeSprintf(buff, MAX_DISPLAY_NAME, "%s.%s", szSMDKey, szServerMetaData);
regid = m_pRegistry->GetId(buff);
if (!regid)
{
m_pRegistry->AddComp(buff);
}
SafeStrCpy(szSMDKey, buff, 256);
// look for comma delimited entries
const char* pCharEntryStart = pszServerMetaData;
const char* pCharEntryEnd = pCharEntryStart;
while (pCharEntryEnd && *pCharEntryEnd)
{
++pCharEntryEnd;
if (*pCharEntryEnd == ',' || !*pCharEntryEnd)
{
// copy next prop request into buffer
strncpy(buff, pCharEntryStart, (UINT32)pCharEntryEnd - (UINT32)pCharEntryStart); /* Flawfinder: ignore */
*(buff+(UINT32)pCharEntryEnd - (UINT32)pCharEntryStart) = '\0';
// see if this prop is in file header (it should be!)
if (HXR_OK == pHeader->GetPropertyCString(buff, pBuffer))
{
// create new registry entry (if one does not exist)
SafeSprintf(szRegKeyName, MAX_DISPLAY_NAME, "%s.%s", szSMDKey, buff);
regid = m_pRegistry->GetId(szRegKeyName);
if (!regid)
{
m_pRegistry->AddStr(szRegKeyName, pBuffer);
}
else
{
// set new value
m_pRegistry->SetStrByName(szRegKeyName, pBuffer);
}
HX_RELEASE(pBuffer);
}
else if (HXR_OK == pHeader->GetPropertyULONG32(buff, ulValue))
{
// create new registry entry
SafeSprintf(szRegKeyName, MAX_DISPLAY_NAME, "%s.%s", szSMDKey, buff);
regid = m_pRegistry->GetId(szRegKeyName);
if (!regid)
{
m_pRegistry->AddInt(szRegKeyName, ulValue);
}
else
{
// set new value
m_pRegistry->SetIntByName(szRegKeyName, ulValue);
}
}
pCharEntryStart = pCharEntryEnd + 1;
}
}
}
HX_RELEASE(pReqHeaders);
}
HX_RELEASE(pRequest);
}
HX_RELEASE(pParentName);
}
return HXR_OK;
}
#endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
HX_RESULT HXSource::SetPlayTimes(UINT32 ulStartTime,
UINT32 ulEndTime,
UINT32 ulDelay,
UINT32 ulDuration)
{
m_ulStartTime = ulStartTime;
m_ulEndTime = ulEndTime;
/* We do not handle Delay field for now */
m_ulDelay = ulDelay;
m_ulRestrictedDuration = ulDuration;
if (m_ulEndTime > 0)
{
m_bCustomEndTime = TRUE;
}
else
{
m_bCustomEndTime = FALSE;
}
return HXR_OK;
}
HX_RESULT
HXSource::UpdatePlayTimes(IHXValues* pValues)
{
HX_RESULT rc = HXR_OK;
char szStart[] = "Start";
char szEnd[] = "End";
char szDelay[] = "Delay";
char szDuration[] = "Duration";
UINT32 ulStartTime = 0;
UINT32 ulEndTime = 0;
UINT32 ulDelay = 0;
UINT32 ulRestrictedDuration = 0;
pValues->GetPropertyULONG32(szStart, ulStartTime);
pValues->GetPropertyULONG32(szEnd, ulEndTime);
pValues->GetPropertyULONG32(szDelay, ulDelay);
pValues->GetPropertyULONG32(szDuration, ulRestrictedDuration);
if (ulStartTime != m_ulStartTime ||
ulEndTime != m_ulEndTime ||
ulDelay != m_ulDelay ||
ulRestrictedDuration != m_ulRestrictedDuration)
{
SetPlayTimes(ulStartTime, ulEndTime, ulDelay, ulRestrictedDuration);
rc = AdjustClipTime();
}
return rc;
}
ULONG32
HXSource::GetPerfectPlayTime(void)
{
ULONG32 ulCurrentPlayTime = m_pPlayer ? m_pPlayer->GetCurrentPlayTime() : 0;
ULONG32 result = m_bPerfectPlay ? m_ulPerfectPlayTime : m_ulBufferedPlayTime;
if (m_ulDuration != 0)
{
// mPlaybackLength is in Milliseconds, we want to calculate
// playback in seconds...
ULONG32 playbackTimeLeftInClip =
((m_ulDuration > ulCurrentPlayTime ? m_ulDuration - ulCurrentPlayTime : 0) /1000)+1;
/* Perfect Play entire clip ONLY if user has chosen PerfectPlay specifically
* If we internally go in buffered play mode, always use perfect play time
* setting.
*/
if (m_bPerfectPlay)
{
if (m_bPerfectPlayEntireClip)
{
result = playbackTimeLeftInClip;
}
else
{
result = min(m_ulPerfectPlayTime, playbackTimeLeftInClip);
}
}
else // if (m_bBufferedPlay)
{
result = min(m_ulBufferedPlayTime, playbackTimeLeftInClip);
}
}
// check if enough memory is available to handle the result
if(result > 0)
{
// get 50% of the available memory
ULONG32 maxMemAvail = GetAvailableMemory() / 2;
ULONG32 bytesPerSecond = m_ulAvgBandwidth/8;
ULONG32 maxTimeAvail = maxMemAvail/(bytesPerSecond > 0 ? bytesPerSecond : 1);
// if this is true then we can't buffer the entire clip
if (maxTimeAvail < result)
m_bCannotBufferEntireClip = (m_bPerfectPlayEntireClip) ? TRUE : FALSE;
else
m_bCannotBufferEntireClip = FALSE;
result = min(result,maxTimeAvail);
}
/* Value now returned in ms. */
return 1000*(max(result, PERFECTPLAY_MIN_TIME));
}
STDMETHODIMP
HXSource::ReportRebufferStatus(UINT16 uStreamNumber,
UINT8 unNeeded,
UINT8 unAvailable)
{
STREAM_INFO* pStreamInfo = 0;
// if (m_bDelayed ||
// (m_ulDelay > 0 && m_ulDelay > m_pPlayer->GetCurrentPlayTime()))
if (m_bDelayed)
{
return HXR_OK;
}
DEBUG_OUT(m_pPlayer, DOL_TRANSPORT, (s, "(%p)ReportRebufferStatus %lu %lu %lu", this, uStreamNumber, unNeeded, unAvailable));
if (mStreamInfoTable->Lookup((LONG32) uStreamNumber, (void*& )pStreamInfo))
{
pStreamInfo->m_unNeeded = unNeeded;
pStreamInfo->m_unAvailable = unAvailable;
if (unNeeded > unAvailable)
{
// dfprintf("buff", "reportrebufferstatus: %lu\n", m_pPlayer->GetInternalCurrentPlayTime());
// g_bRahulLog = TRUE;
if (m_bFastStart)
{
DEBUG_OUT(m_pPlayer, DOL_TRANSPORT, (s, "(%p)ALMOST Turbo OFF ReportRebufferStatus", this));
//with surestream audio only clips, rarender may report buffering immediately after resume
if (m_bSureStreamClip)
{
if (CALCULATE_ELAPSED_TICKS(m_ulTurboStartActiveTime, HX_GET_TICKCOUNT()) > 1000)
{
LeaveFastStart(TP_OFF_BY_REBUFFER);
DEBUG_OUT(m_pPlayer, DOL_TRANSPORT, (s, "(%p)Turbo OFF ReportRebufferStatus", this));
}
}
else
{
LeaveFastStart(TP_OFF_BY_REBUFFER);
DEBUG_OUT(m_pPlayer, DOL_TRANSPORT, (s, "(%p)Turbo OFF ReportRebufferStatus", this));
}
}
// log rebuffer action
LogInformation("BUFBEG", NULL);
DoRebuffer();
}
else
{
m_bRebufferingRequired = IsRebufferRequired();
if (!m_bRebufferingRequired)
{
// log rebuffer action
LogInformation("BUFEND", NULL);
}
}
return HXR_OK;
}
return HXR_UNEXPECTED;
}
STDMETHODIMP
HXSource::SetGranularity
(
UINT16 uStreamNumber,
ULONG32 ulGranularity
)
{
STREAM_INFO* pStreamInfo = 0;
if (mStreamInfoTable->Lookup((LONG32) uStreamNumber, (void*& )pStreamInfo))
{
m_pPlayer->SetGranularity(this, uStreamNumber, ulGranularity);
return HXR_OK;
}
else
{
return HXR_OK;
}
return HXR_UNEXPECTED;
}
BOOL
HXSource::TryResume(void)
{
BOOL bResume = FALSE;
// resume the persistent source ASAP
if (m_pSourceInfo && m_pSourceInfo->m_bIsPersistentSource)
{
m_bDelayed = FALSE;
bResume = TRUE;
}
else if (m_bPaused && m_bDelayed && m_pPlayer &&
m_pPlayer->CanBeStarted(this, m_pSourceInfo, m_bPartOfNextGroup))
{
UINT32 ulCurrentTime = m_pPlayer->GetInternalCurrentPlayTime();
UINT32 ulStartTime = 0;
if (m_ulDelay > m_ulPreRollInMs + NETWORK_FUDGE_FACTOR)
{
ulStartTime = m_ulDelay - (m_ulPreRollInMs + NETWORK_FUDGE_FACTOR);
}
if (ulCurrentTime >= ulStartTime)
{
m_bDelayed = FALSE;
bResume = TRUE;
}
if (!m_bIsPreBufferingStarted)
{
m_bIsPreBufferingStarted = TRUE;
bResume = TRUE;
}
}
else if (m_bPrefetch)
{
bResume = TRUE;
}
if (bResume && CanBeResumed())
{
if (m_pSourceInfo)
{
m_pSourceInfo->Register();
}
m_bResumePending = TRUE;
}
return bResume;
}
BOOL
HXSource::IsAnyAudioStream(void)
{
IHXAudioPlayer* pAudioPlayer = NULL;
BOOL bAtLeastOneAudioStream = FALSE;
if (!m_pPlayer)
{
return FALSE;
}
m_pPlayer->QueryInterface(IID_IHXAudioPlayer, (void **) &pAudioPlayer);
UINT16 uNumAudioStreams = pAudioPlayer->GetAudioStreamCount();
for (UINT16 i = 0; i < uNumAudioStreams && !bAtLeastOneAudioStream; i++)
{
IHXAudioStream* pAudioStream = pAudioPlayer->GetAudioStream(i);
IHXValues* pHeader = pAudioStream->GetStreamInfo();
pAudioStream->Release();
if (!pHeader)
{
continue;
}
if (IsAudioStreamFromThisSource(pHeader))
{
bAtLeastOneAudioStream = TRUE;
pHeader->Release();
break;
}
pHeader->Release();
}
if (!bAtLeastOneAudioStream)
{
IHXValues* pHeader = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -