📄 hxsrc.cpp
字号:
HXSource::IsRebufferRequired(void)
{
BOOL bResult = FALSE;
STREAM_INFO* pStreamInfo = NULL;
// Check if all streams are doing OK
for (CHXMapLongToObj::Iterator ndxStrm = mStreamInfoTable->Begin();
ndxStrm != mStreamInfoTable->End(); ++ndxStrm)
{
pStreamInfo = (STREAM_INFO*) (*ndxStrm);
if (pStreamInfo->m_unNeeded > pStreamInfo->m_unAvailable)
{
bResult = TRUE;
break;
}
}
return bResult;
}
BOOL
HXSource::IsRebufferDone(void)
{
BOOL bResult = TRUE;
if (m_pSourceInfo)
{
bResult = m_pSourceInfo->IsRebufferDone();
}
return bResult;
}
void
HXSource::ScheduleProcessCallback()
{
if (m_pSourceInfo)
{
m_pSourceInfo->ScheduleProcessCallback();
}
}
#if defined(HELIX_FEATURE_HYPER_NAVIGATE)
/************************************************************************
* Method:
* IHXHyperNavigate::GoToURL
* Purpose:
* Acts as a proxy for actual hypernavigate interface.
* Is used to convert any relative URLs to absolute URLs
*/
STDMETHODIMP
HXSource::GoToURL(const char* pURL, const char* pTarget)
{
return Execute(pURL, pTarget, NULL, NULL, NULL);
}
/************************************************************************
* Method:
* IHXHyperNavigate2::Execute
* Purpose:
*
* Parameters:
* pURL: URL (absolute or relative)
* pTargetInstance:
* pTargetApplication:
* pTargetRegion:
* pParams:
*/
STDMETHODIMP
HXSource::Execute(const char* pURL,
const char* pTargetInstance,
const char* pTargetApplication,
const char* pTargetRegion,
IHXValues* pParams)
{
HX_RESULT theErr = HXR_OK;
CHXString newURL = pURL;
// pURL = "rogers.rt";
// if (pTargetInstance &&
// stricmp(pTargetInstance, "_player") == 0 &&
if (ShouldConvert(pTargetInstance) &&
pURL &&
strnicmp(pURL, URL_COMMAND, sizeof(URL_COMMAND) - 1) != 0 )
{
CHXURL urlObj(pURL);
IHXValues* pHeader = urlObj.GetProperties();
IHXBuffer* pBuffer = NULL;
if(pHeader &&
m_pszURL &&
HXR_OK != pHeader->GetPropertyBuffer(PROPERTY_SCHEME, pBuffer))
{
// relative URL
// if it starts with '/', make it relative to the root of
// the URL prefix
CHXString urlPrefix, urlRoot;
char* pURLFragment = NULL;
theErr = CHXURL::GeneratePrefixRootFragment(m_pszURL, urlPrefix, urlRoot, pURLFragment);
HX_VECTOR_DELETE(pURLFragment);
if (!theErr)
{
if(*pURL == '/')
{
newURL = urlRoot + pURL;
}
else
{
newURL = urlPrefix + pURL;
}
}
}
HX_RELEASE(pBuffer);
HX_RELEASE(pHeader);
}
AddRef();
HX_ASSERT(m_pPlayer && m_pPlayer->m_pHyperNavigate);
if (m_pPlayer && m_pPlayer->m_pHyperNavigate)
{
theErr = m_pPlayer->m_pHyperNavigate->ExecuteWithContext(newURL,
pTargetInstance, pTargetApplication, pTargetRegion,
pParams, (IUnknown*) (IHXStreamSource*) this);
}
Release();
return theErr;
}
#endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
STDMETHODIMP
HXSource::GetTotalBuffering(UINT16 uStreamNumber,
REF(INT64) llLowestTimestamp,
REF(INT64) llHighestTimestamp,
REF(UINT32) ulNumBytes,
REF(BOOL) bDone)
{
HX_RESULT res = HXR_NO_DATA;
llLowestTimestamp = 0;
llHighestTimestamp = 0;
ulNumBytes = 0;
bDone = FALSE;
STREAM_INFO* pStreamInfo;
if (mStreamInfoTable->Lookup((LONG32) uStreamNumber, (void*& )pStreamInfo))
{
HXBufferingState& bufState = pStreamInfo->BufferingState();
BOOL bUseTransportStats = FALSE;
INT64 llTransportLowTS = 0;
INT64 llTransportHighTS = 0;
UINT32 ulTransportBytes = 0;
BOOL bTransportDone = FALSE;
if (!IsLocalSource() &&
(HXR_OK == GetCurrentBuffering(uStreamNumber,
llTransportLowTS,
llTransportHighTS,
ulTransportBytes,
bTransportDone)))
{
bufState.UpdateTransportStats(llTransportLowTS,
llTransportHighTS,
ulTransportBytes,
bTransportDone);
bUseTransportStats = TRUE;
// Update bDone with what the transport says.
bDone = bTransportDone;
}
res = bufState.GetBufferingStats(llLowestTimestamp,
llHighestTimestamp,
ulNumBytes,
bUseTransportStats);
}
return res;
}
/*
* All relative URLs are converted to absolute URLs unless the
* original request (ram/smil) passed in OpenRequest/OpenURL()
* is a mem: URL AND the target is not _player.
*
* This fixes relative URLs being hurled to the browser using events
* come from the same location as the .ram file. (Broadcase usage case)
* PR 31352
*
* This also fixes content on CD-ROMs where relative URLs being hurled
* to the browser using events come from the same location as
* the .rm file in which they are merged.
* PR 23489
*/
BOOL HXSource::ShouldConvert(const char* pTargetInstance)
{
if (pTargetInstance &&
stricmp(pTargetInstance, "_player") == 0)
{
return TRUE;
}
const char* pPlayerURL = NULL;
IHXRequest* pPlayerRequest = NULL;
if (m_pPlayer)
{
m_pPlayer->GetRequest(pPlayerRequest);
if (pPlayerRequest)
{
pPlayerRequest->GetURL(pPlayerURL);
}
}
HX_RELEASE(pPlayerRequest);
if (pPlayerURL && ::strncasecmp(pPlayerURL, "mem:", 4) == 0)
{
return FALSE;
}
return TRUE;
}
void
HXSource::MergeUpgradeRequest(BOOL bAddDefault /*= FALSE*/, char* pUpgradeString /* = NULL*/)
{
#if defined(HELIX_FEATURE_AUTOUPGRADE)
if (m_pPlayer &&
bAddDefault &&
(!m_pUpgradeCollection || m_pUpgradeCollection->GetCount() == 0))
{
if (!m_pUpgradeCollection)
{
m_pUpgradeCollection = new HXUpgradeCollection;
}
if (!pUpgradeString)
{
pUpgradeString = "Missing Component";
}
IHXBuffer* pPluginID = (IHXBuffer*) new CHXBuffer;
pPluginID->AddRef();
pPluginID->Set((const UINT8*)pUpgradeString, strlen(pUpgradeString) + 1);
m_pUpgradeCollection->Add(eUT_Required, pPluginID, 0, 0);
pPluginID->Release();
}
if (m_pPlayer && m_pUpgradeCollection && m_pUpgradeCollection->GetCount() > 0)
{
UINT32 ulCount = m_pUpgradeCollection->GetCount();
IHXUpgradeCollection* pPlayerUpgrade;
m_pPlayer->QueryInterface(IID_IHXUpgradeCollection, (void**) &pPlayerUpgrade);
for (UINT32 i = 0; i < ulCount; i++)
{
HXUpgradeType upgradeType;
IHXBuffer* pPluginId = (IHXBuffer*) new CHXBuffer;
UINT32 majorVersion;
UINT32 minorVersion;
pPluginId->AddRef();
// GetAt is a non-COM like API. It expects pPluginID to be allocated by the user
// and does not perform an addref either!
m_pUpgradeCollection->GetAt(i, upgradeType, pPluginId, majorVersion, minorVersion);
pPlayerUpgrade->Add(upgradeType, pPluginId, majorVersion, minorVersion);
pPluginId->Release();
}
pPlayerUpgrade->Release();
m_pUpgradeCollection->RemoveAll();
}
#endif /* HELIX_FEATURE_AUTOUPGRADE */
}
void
HXSource::ClearUpgradeRequest()
{
#if defined(HELIX_FEATURE_AUTOUPGRADE)
if (m_pUpgradeCollection)
{
m_pUpgradeCollection->RemoveAll();
}
#endif /* HELIX_FEATURE_AUTOUPGRADE */
}
void
HXSource::EnterPrefetch(PrefetchType prefetchType, UINT32 ulPrefetchValue)
{
m_bPrefetch = TRUE;
m_prefetchType = prefetchType;
m_ulPrefetchValue = ulPrefetchValue;
return;
}
void
HXSource::LeavePrefetch(void)
{
m_bPrefetch = FALSE;
// send prefetch notification so that SMIL
// renderer can resolve the duration on this prefetch track
if (m_pSourceInfo)
{
m_pPlayer->PrefetchTrackDone(m_pSourceInfo->m_uGroupID,
m_pSourceInfo->m_uTrackID,
HXR_OK);
}
return;
}
void
HXSource::SetSoundLevel(UINT16 uSoundLevel, BOOL bReflushAudioDevice)
{
#if defined(HELIX_FEATURE_SMIL_SOUNDLEVEL)
CHXAudioPlayer* pAudioPlayer = NULL;
CHXAudioStream* pCHXAudioStream = NULL;
CHXSimpleList* pAudioStreamList = NULL;
if (!m_pPlayer)
{
goto cleanup;
}
pAudioPlayer = m_pPlayer->GetAudioPlayer();
if (!pAudioPlayer)
{
goto cleanup;
}
pAudioPlayer->AddRef();
if (HXR_OK == CollectAudioStreams(pAudioStreamList) && pAudioStreamList)
{
pAudioPlayer->SetSoundLevel(pAudioStreamList, uSoundLevel, bReflushAudioDevice);
ReleaseAudioStreams(pAudioStreamList);
HX_DELETE(pAudioStreamList);
}
HX_RELEASE(pAudioPlayer);
cleanup:
#endif /* HELIX_FEATURE_SMIL_SOUNDLEVEL */
return;
}
void
HXSource::SetAudioDeviceReflushHint(void)
{
#if defined(HELIX_FEATURE_SOUNDLEVEL)
CHXAudioPlayer* pAudioPlayer = NULL;
CHXSimpleList* pAudioStreamList = NULL;
if (!m_pPlayer)
{
goto cleanup;
}
pAudioPlayer = m_pPlayer->GetAudioPlayer();
if (!pAudioPlayer)
{
goto cleanup;
}
pAudioPlayer->AddRef();
if (HXR_OK == CollectAudioStreams(pAudioStreamList) && pAudioStreamList)
{
pAudioPlayer->ManageAudioStreams(pAudioStreamList, CHXAudioPlayer::STR_SETHINT);
ReleaseAudioStreams(pAudioStreamList);
HX_DELETE(pAudioStreamList);
}
HX_RELEASE(pAudioPlayer);
cleanup:
#endif /* HELIX_FEATURE_SOUNDLEVEL */
return;
}
void
HXSource::LeaveFastStart(TurboPlayOffReason leftReason)
{
m_turboPlayStats.tpOffReason = leftReason;
m_bFastStart = FALSE;
}
void
HXSource::DeleteAllEvents()
{
if (m_PacketBufferList.GetCount() > 0)
{
LISTPOSITION pos = m_PacketBufferList.GetHeadPosition();
while (pos != NULL)
{
CHXEvent* pTempEvent = (CHXEvent*) m_PacketBufferList.GetNext(pos);
delete pTempEvent;
}
m_PacketBufferList.RemoveAll();
}
}
void
HXSource::SetMinimumPreroll(ULONG32 ulMinimumAudioPreroll, ULONG32 ulMinimumStartingPreroll)
{
UINT32 ulTotalMinimumPreroll = 0;
if (m_pPlayer)
{
// get the user-set minimum preroll
m_pPlayer->GetMinimumPreroll(ulTotalMinimumPreroll);
}
if (IsAnyAudioStream())
{
m_ulPreRollInMs += ulMinimumAudioPreroll;
}
if (m_ulPreRollInMs < ulTotalMinimumPreroll)
{
m_ulPreRollInMs = ulTotalMinimumPreroll;
}
DEBUG_OUT(m_pPlayer, DOL_TRANSPORT, (s, "(%p)Preroll: %lu MinPreroll %lu MinAudioPreroll %lu", this, m_ulPreRollInMs, ulTotalMinimumPreroll, ulMinimumStartingPreroll));
m_pBufferManager->SetMinimumPreroll(IsLocalSource() | m_bPerfectPlay,
ulTotalMinimumPreroll,
ulMinimumStartingPreroll);
}
HX_RESULT
HXSource::SendHeaderToRecordControl(BOOL bFileHeader, IHXValues* pHeader)
{
#if defined(HELIX_FEATURE_RECORDCONTROL)
HX_RESULT nResult = HXR_OK;
if(m_pRecordControl && pHeader)
{
if(bFileHeader)
nResult = m_pRecordControl->OnFileHeader(pHeader);
else
nResult = m_pRecordControl->OnStreamHeader(pHeader);
if(nResult != HXR_OK)
{
m_bPlayFromRecordControl = FALSE;
if(nResult != HXR_RECORD)
HX_RELEASE(m_pRecordControl);
}
}
return nResult;
#else
return HXR_NOTIMPL;
#endif /* HELIX_FEATURE_RECORDCONTROL */
}
void
HXSource::ProcessFileHeader(void)
{
UINT32 bNonSeekAble = 0;
IHXBuffer* pTitle = NULL;
IHXBuffer* pAuthor = NULL;
IHXBuffer* pCopyright = NULL;
IHXBuffer* pAbstract = NULL;
IHXBuffer* pDescription = NULL;
IHXBuffer* pKeywords = NULL;
IHXValues* pValues = NULL;
if (m_pURL)
{
pValues = m_pURL->GetOptions();
}
// retrieve the TAC from the URL
if (pValues)
{
pValues->GetPropertyBuffer("Title", pTitle);
pValues->GetPropertyBuffer("Author", pAuthor);
pValues->GetPropertyBuffer("Copyright", pCopyright);
pValues->GetPropertyBuffer("Abstract", pAbstract);
pValues->GetPropertyBuffer("Description", pDescription);
pValues->GetPropertyBuffer("Keywords", pKeywords);
//#define LOSS_HACK
#ifdef LOSS_HACK
UINT32 ulLoss = 0;
if (HXR_OK == pValues->GetPropertyULONG32("Loss", ulLoss))
{
m_ulLossHack = ulLoss;
/* Initialize random number generator */
::srand((unsigned int) HX_GET_TICKCOUNT());
}
#endif /*LOSS_HACK*/
}
if (m_pFileHeader)
{
if (!pTitle) m_pFileHeader->GetPropertyBuffer("Title", pTitle);
if (!pAuthor) m_pFileHeader->GetPropertyBuffer("Author", pAuthor);
if (!pCopyright) m_pFileHeader->GetPropertyBuffer("Copyright", pCopyright);
if (!pDescription) m_pFileHeader->GetPropertyCString("Description", pDescription);
if (!pAbstract) m_pFileHeader->GetPropertyCString("Abstract", pAbstract);
if (!pKeywords) m_pFileHeader->GetPropertyCString("Keywords", pKe
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -