📄 progdown.cpp
字号:
// If there was a size monitoring callback
// scheduled, then cancel it
if (m_pStatCallback)
{
m_pStatCallback->Cancel(m_pScheduler);
}
}
UINT32 CProgressiveDownloadMonitor::GetFileSizeNow()
{
UINT32 ulRet = 0;
if (m_pDataFile)
{
// Stat the file
struct stat sStat;
if (SUCCEEDED(m_pDataFile->Stat(&sStat)))
{
// Set the return value
ulRet = (UINT32) sStat.st_size;
}
}
return ulRet;
}
void CProgressiveDownloadMonitor::MonitorFileSize()
{
MLOG_PD(NULL, "CProgressiveDownloadMonitor::MonitorFileSize() this=0x%08x tick=%lu\n",
this, HX_GET_BETTERTICKCOUNT());
// Save the current m_bIsProgressive value
BOOL bTmp = m_bIsProgressive;
// Get the file size and tick count
UINT32 ulFileSize = GetFileSizeNow();
UINT32 ulTick = HX_GET_BETTERTICKCOUNT();
// Is the file size the same as m_ulLastFileSize?
if (ulFileSize != m_ulLastFileSize)
{
MLOG_PD(NULL, "\tNewFileSize=%lu\n", ulFileSize);
// The filesize has changed, so we know
// this file is progressive
m_bIsProgressive = TRUE;
// Reset the former progressive retry count to
// its initial value
m_ulFormerProgRetryCount = m_ulFormerProgRetryInit;
// Reset the not progressive retry count to
// its initial value
m_ulNotProgRetryCount = m_ulNotProgRetryInit;
// If the file size is different even once,
// then this file has a history of being progressive.
// We keep this variable around in addition to
// m_bIsProgressive since m_bIsProgressive can change
// when the file finishes downloading or when the
// download agent pauses. Since we want to treat files
// which have a history of being progressive differently
// than files which don't, we need to keep m_bHasBeenProgressive.
m_bHasBeenProgressive = TRUE;
// Update the last file size
m_ulLastFileSize = ulFileSize;
// Update the tick count
m_ulTickAtLastFileSize = ulTick;
}
else
{
// The filesize is the same. How
// long has it been the same?
UINT32 ulDiff = CALCULATE_ELAPSED_TICKS(m_ulTickAtLastFileSize, ulTick);
// If the file size has been the
// same for at last m_ulFinishedTime
// milliseconds, then we assume it has
// finished downloading
if (ulDiff > m_ulFinishedTime && m_bIsProgressive)
{
MLOG_PD(NULL, "\tFile has been %lu bytes for %lu ms. DECLARING FINISHED.\n",
ulFileSize, ulDiff);
m_bIsProgressive = FALSE;
}
}
// Did the value of m_bIsProgressive change?
if (bTmp != m_bIsProgressive)
{
// Update the registry statistics
UpdateRegistryStats();
}
}
void CProgressiveDownloadMonitor::StatCallback(void* pArg)
{
if (pArg)
{
CProgressiveDownloadMonitor* pObj = (CProgressiveDownloadMonitor*) pArg;
pObj->MonitorFileSize();
pObj->ScheduleStatCallback();
}
}
void CProgressiveDownloadMonitor::ProgCallback(void* pArg)
{
MLOG_PD(NULL, "CProgressiveDownloadMonitor::ProgCallback(0x%08x) tick=%lu\n",
pArg, HX_GET_BETTERTICKCOUNT());
if (pArg)
{
CProgressiveDownloadMonitor* pObj = (CProgressiveDownloadMonitor*) pArg;
if (pObj->m_pResponse)
{
pObj->m_pResponse->ProgressiveCallback();
}
}
}
void CProgressiveDownloadMonitor::CheckPreferenceValues(REF(BOOL) rbMonitorEnabled,
REF(UINT32) rulStatCallbackInterval,
REF(UINT32) rulProgCallbackInterval,
REF(UINT32) rulFinishedTime,
REF(UINT32) rulFormerProgRetryCount,
REF(UINT32) rulNotProgRetryCount)
{
if (m_pContext)
{
IHXPreferences* pPrefs = NULL;
m_pContext->QueryInterface(IID_IHXPreferences, (void**) &pPrefs);
if (pPrefs)
{
ReadPrefBOOL(pPrefs, "ProgressiveDownload\\FileSizeMonitorEnabled", rbMonitorEnabled);
ReadPrefINT32(pPrefs, "ProgressiveDownload\\FileSizeCheckInterval", rulStatCallbackInterval);
ReadPrefINT32(pPrefs, "ProgressiveDownload\\FailureRetryInterval", rulProgCallbackInterval);
ReadPrefINT32(pPrefs, "ProgressiveDownload\\DeclareFinishedDuration", rulFinishedTime);
ReadPrefINT32(pPrefs, "ProgressiveDownload\\FormerProgressiveRetryCount", rulFormerProgRetryCount);
ReadPrefINT32(pPrefs, "ProgressiveDownload\\NotProgressiveRetryCount", rulNotProgRetryCount);
MLOG_PD(NULL,
"\tFileSizeMonitorEnabled = %lu\n"
"\tFileSizeCheckInterval = %lu\n"
"\tFailureRetryInterval = %lu\n"
"\tDeclareFinishedDuration = %lu\n"
"\tFormerProgressiveRetryCount = %lu\n"
"\tNotProgressiveRetryCount = %lu\n",
rbMonitorEnabled, rulStatCallbackInterval,
rulProgCallbackInterval, rulFinishedTime,
rulFormerProgRetryCount, rulNotProgRetryCount);
}
HX_RELEASE(pPrefs);
}
}
HX_RESULT CProgressiveDownloadMonitor::InitRegistryStats()
{
HX_RESULT retVal = HXR_FAIL;
if (m_pContext && m_pRegistry && m_pDataFile)
{
// Get the source registry ID
IHXRegistryID* pRegistryID = NULL;
retVal = m_pContext->QueryInterface(IID_IHXRegistryID, (void**) &pRegistryID);
if (SUCCEEDED(retVal))
{
UINT32 ulSourceRegistryID = 0;
retVal = pRegistryID->GetID(ulSourceRegistryID);
if (SUCCEEDED(retVal))
{
// Get the source property name - this will
// be something like "Statistics.Player0.Source0"
IHXBuffer* pSourceName = NULL;
retVal = m_pRegistry->GetPropName(ulSourceRegistryID, pSourceName);
if (SUCCEEDED(retVal))
{
// Construct the URL property name
CHXString cPropName((const char*) pSourceName->GetBuffer());
cPropName += ".URL";
// Construct the URL property value
CHXString cPropVal("file://");
IHXBuffer* pNameBuf = NULL;
if (m_pDataFile->Name(pNameBuf))
{
cPropVal += (const char*) pNameBuf->GetBuffer();
}
HX_RELEASE(pNameBuf);
// Put the URL property value into an IHXBuffer
IHXBuffer* pPropVal = NULL;
CreateStringBuffer(pPropVal, (const char*) cPropVal, m_pContext);
if (pPropVal)
{
// Does this property already exist?
IHXBuffer* pTmp = NULL;
if (SUCCEEDED(m_pRegistry->GetStrByName((const char*) cPropName, pTmp)))
{
// It does already exist
//
// Set the new value
m_pRegistry->SetStrByName((const char*) cPropName, pPropVal);
// Get the registry ID
m_ulURLRegistryID = m_pRegistry->GetId((const char*) cPropName);
}
else
{
// It does not already exist, so create it
// and get the registry id at the same time
m_ulURLRegistryID = m_pRegistry->AddStr((const char*) cPropName, pPropVal);
}
HX_RELEASE(pTmp);
}
HX_RELEASE(pPropVal);
// Construct the IsProgressive property name
cPropName = (const char*) pSourceName->GetBuffer();
cPropName += ".IsProgressive";
// Does this property already exist?
INT32 lTmp = 0;
if (SUCCEEDED(m_pRegistry->GetIntByName((const char*) cPropName, lTmp)))
{
// It DOES already exist
//
// Set the new value
m_pRegistry->SetIntByName((const char*) cPropName, (m_bIsProgressive ? 1 : 0));
// Get the registry id
m_ulIsProgRegistryID = m_pRegistry->GetId((const char*) cPropName);
}
else
{
// It does NOT already exist
//
// Create the IsProgressive property and get
// the registry id at the same time
m_ulIsProgRegistryID = m_pRegistry->AddInt((const char*) cPropName,
(m_bIsProgressive ? 1 : 0));
}
}
HX_RELEASE(pSourceName);
}
}
HX_RELEASE(pRegistryID);
}
return retVal;
}
void CProgressiveDownloadMonitor::UpdateRegistryStats()
{
MLOG_PD(NULL, "CProgressiveDownloadMonitor::UpdateRegistryStats() this=0x%08x\n", this);
// Right now the only thing we are updating
// is the IsProgressive property. We assume
// that the URL property will never need to
// change during playback.
if (m_pRegistry && m_ulIsProgRegistryID)
{
m_pRegistry->SetIntById(m_ulIsProgRegistryID, (m_bIsProgressive ? 1 : 0));
}
}
void CProgressiveDownloadMonitor::ScheduleStatCallback()
{
if (m_pStatCallback && m_bMonitorEnabled)
{
MLOG_PD(NULL, "CProgressiveDownloadMonitor::ScheduleStatCallback() this=0x%08x m_ulCurStatInterval=%lu\n",
this, m_ulCurStatInterval);
m_pStatCallback->ScheduleRelative(m_pScheduler, m_ulCurStatInterval);
// We start off with a small stat interval
// and double the interval every time until
// we reach m_ulStatCallbackInterval
if (m_ulCurStatInterval < m_ulStatCallbackInterval)
{
m_ulCurStatInterval *= 2;
if (m_ulCurStatInterval > m_ulStatCallbackInterval)
{
m_ulCurStatInterval = m_ulStatCallbackInterval;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -