⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fbbufctl.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    HX_RELEASE(m_pPrefs);    HX_RELEASE(m_pStatus);    ChangeState(csNotInitialized);    return HXR_OK;}/************************************************************************ *      Method: *          IHXCallback::Func *      Purpose: *          This is the function that will be called when a callback is *          to be executed. */STDMETHODIMP HXFeedbackBufferControl::Func(THIS){    DEBUG_OUT(m_pErrMsg, DOL_BUFFER_CONTROL, (s, "FBBC::Func"));    if (Initialized())    {        UINT32 ulNewBandwidth = 0;        if (csPlaying == m_state)        {            UINT32 ulTotalBits = 0;            UINT32 ulControlBits = 0;            UINT32 ulNewBandwidth = 0;                        GetControlData(ulTotalBits, ulControlBits);                        if (HXR_OK == Control(ulControlBits, ulNewBandwidth))            {                SetBandwidth(ulNewBandwidth);            }        }        else if (csBuffering == m_state)        {            // Bandwidth used during buffering and seeking            SetBandwidth(m_ulClipBw);        }        ScheduleCallback();    }    return HXR_OK;}void HXFeedbackBufferControl::ChangeState(ControlState newState){    if (csError != m_state)    {        DEBUG_OUT(m_pErrMsg, DOL_BUFFER_CONTROL,                  (s, "FBBC::CS : %lu %d -> %d",                    HX_GET_TICKCOUNT(), m_state, newState));        m_state = newState;    }    else    {        DEBUG_OUT(m_pErrMsg, DOL_BUFFER_CONTROL,                  (s, "FBBC::CS : Tried to leave error state"));        HX_ASSERT(csError == m_state);    }}void HXFeedbackBufferControl::ScheduleCallback(){    if (m_pScheduler)    {        UINT32 uDelayInMs = (UINT32)(m_control.SamplePeriod() * 1000);        m_lastTime.tv_sec += uDelayInMs / 1000;        m_lastTime.tv_usec += (uDelayInMs * 1000) * 1000;                m_callbackHandle = m_pScheduler->AbsoluteEnter(this, m_lastTime);    }}void HXFeedbackBufferControl::StartCallback(){    if (m_pScheduler)    {        m_lastTime = m_pScheduler->GetCurrentSchedulerTime();                ScheduleCallback();    }}void HXFeedbackBufferControl::StopCallback(){    if (m_pScheduler && m_callbackHandle)    {        m_pScheduler->Remove(m_callbackHandle);        m_callbackHandle = 0;    }}HX_RESULT HXFeedbackBufferControl::GetBwInfo(REF(UINT32) ulClipBw,                                             REF(UINT16) nControlStream,                                              REF(UINT32) ulControlBw){    HX_RESULT res = HXR_OK;    if (!m_pSource)    {        res = HXR_FAILED;    }    else if (m_pSource->GetStreamCount() == 0)    {        res = HXR_NO_DATA;    }    else    {        ulClipBw = 0;        nControlStream = 0;        ulControlBw = 0;                UINT32 ulHighestBw = 0;        UINT16 nHighestBwStream = 0;        BOOL bFoundAudio = FALSE;        UINT32 ulLowAudioBw = 0;        UINT16 nLowestBwAudioStream = 0;        for (UINT16 i = 0; (HXR_OK == res) && (i < m_pSource->GetStreamCount()); i++)        {            UINT32 ulStreamBw = 0;            if (HXR_OK == GetStreamBw(i, ulStreamBw))            {                if (ulStreamBw > ulHighestBw)                {                    ulHighestBw = ulStreamBw;                    nHighestBwStream = i;                }                if (IsAudioStream(i) &&                    (!bFoundAudio || (ulStreamBw < ulLowAudioBw)))                {                    bFoundAudio = TRUE;                    ulLowAudioBw = ulStreamBw;                    nLowestBwAudioStream = i;                }                ulClipBw += ulStreamBw;            }        }        if (bFoundAudio)        {            nControlStream = nLowestBwAudioStream;            ulControlBw = ulLowAudioBw;        }        else        {            nControlStream = nHighestBwStream;            ulControlBw = ulHighestBw;        }    }    return res;}HX_RESULT HXFeedbackBufferControl::GetStreamBw(UINT16 uStreamNumber,                                      REF(UINT32) ulBandwidth){    HX_RESULT res = HXR_FAILED;    if (m_pSource)    {        IUnknown* pUnk = NULL;        res = m_pSource->GetStream(uStreamNumber, pUnk);                if (HXR_OK == res)        {            IHXASMProps* pProps = NULL;                        res = pUnk->QueryInterface(IID_IHXASMProps, (void**)&pProps);            if (HXR_OK == res)            {                res = pProps->GetBandwidth(ulBandwidth);                                pProps->Release();            }            pUnk->Release();        }    }    return res;}BOOL HXFeedbackBufferControl::IsAudioStream(UINT16 uStreamNumber){    BOOL bRet = FALSE;    if (m_pSource)    {        IUnknown* pUnk = NULL;        IHXStream* pStream = NULL;        IHXValues* pHeader = NULL;        IHXBuffer* pMimetype = NULL;        if ((HXR_OK == m_pSource->GetStream(uStreamNumber, pUnk)) &&            (HXR_OK == pUnk->QueryInterface(IID_IHXStream, (void**)&pStream))&&            (NULL != (pHeader = pStream->GetHeader())) &&            (HXR_OK == pHeader->GetPropertyCString("MimeType", pMimetype)) &&            (!strncasecmp("audio", (char*)pMimetype->GetBuffer(), 5)))        {            bRet = TRUE;        }        HX_RELEASE(pMimetype);        HX_RELEASE(pHeader);        HX_RELEASE(pStream);        HX_RELEASE(pUnk);    }    return bRet;}void HXFeedbackBufferControl::GetControlData(REF(UINT32) ulTotalBits,                                             REF(UINT32) ulControlBits){    ulTotalBits = 0;    ulControlBits = 0;        for (UINT16 i = 0; i < m_pSource->GetStreamCount(); i++)    {        UINT32 ulBytes;                HX_RESULT res = HXR_FAILED;        INT64 llLowTS;        INT64 llHighTS;        BOOL bDone;        res = m_pBufferStats->GetTotalBuffering(i,                                                 llLowTS, llHighTS,                                                ulBytes,                                                bDone);        if (HXR_OK == res)        {            ulTotalBits += 8 * ulBytes;                        if (i == m_nControlStream)            {                ulControlBits = 8 * ulBytes;            }        }    }}HX_RESULT HXFeedbackBufferControl::Control(UINT32 ulControlBits,                                            REF(UINT32) ulNewBandwidth){    UINT32 ulSetPoint = m_control.SetPoint();    INT32 error = (INT32)ulSetPoint - (INT32)ulControlBits;        double errorFactor = error;    ulNewBandwidth = m_control.Control(ulControlBits);    ulNewBandwidth = ControlToTotal(ulNewBandwidth);    if (ulSetPoint)    {        errorFactor = (double)error / (double)ulSetPoint;    }    DEBUG_OUT(m_pErrMsg, DOL_BUFFER_CONTROL,               (s, "FBBC::CTL %lu %d %lu %lu %2.4f",               HX_GET_TICKCOUNT(),               error,                ulNewBandwidth,                ulControlBits,               errorFactor));        return HXR_OK;}void HXFeedbackBufferControl::SetBandwidth(UINT32 ulBandwidth){    DEBUG_OUT(m_pErrMsg, DOL_BUFFER_CONTROL,               (s, "FBBC::SB %lu %lu ",                HX_GET_TICKCOUNT(), ulBandwidth));    if (m_pThin)    {        m_pThin->SetDeliveryBandwidth(ulBandwidth, 0);    }}HX_RESULT HXFeedbackBufferControl::ReadPrefSettings(){    HX_RESULT res = HXR_FAILED;        UINT32 ulMin = 1000;    UINT32 ulMax = 0;    ReadPrefINT32(m_pPrefs, "MinDelBandwidth", ulMin);    /* Get initial bandwidth guess from Prefs */    if (HXR_OK == ReadPrefINT32(m_pPrefs, "Bandwidth", ulMax))    {        UINT32 ulSustainFactor = 0;        /* See if we have a sustainable bandwidth factor */        if (HXR_OK == ReadPrefINT32(m_pPrefs, "SustainableBwFactor",                                     ulSustainFactor))        {            /* clamp value to 0 <= ulTemp <= 100 range */            if (ulSustainFactor > 100)            {                ulSustainFactor = 100;            }                        /* Apply factor */            ulMax = (((ulMax / 100) * ulSustainFactor) +                      (((ulMax % 100) * ulSustainFactor) / 100));        }        if (ulMax > 0)        {            if (ulMin > ulMax)            {                // Make the minimum bandwidh 1% of the max                // rounded up to the next bit/second                ulMin = (ulMax + 99) / 100;            }                        m_control.SetLimits(ulMin, ulMax);                        res = HXR_OK;        }    }    return res;}void HXFeedbackBufferControl::SetTransportByteLimits(UINT32 ulClipBw){    UINT32 ulTotalByteLimit = 0;    IHXTransportBufferLimit* pBufLimit = NULL;    ReadPrefINT32(m_pPrefs, "TransportByteLimit", ulTotalByteLimit);    if (m_pSource &&         (HXR_OK == m_pSource->QueryInterface(IID_IHXTransportBufferLimit,                                             (void**)&pBufLimit)))    {        // Divide the byte limit amoung the streams        for (UINT16 i = 0; i < m_pSource->GetStreamCount(); i++)        {            UINT32 ulStreamBw = 0;            if (HXR_OK == GetStreamBw(i, ulStreamBw))            {                // Byte limit for this stream is                // (ulTotalByteLimit * ulStreamBw) / ulClipBw                UINT32 ulByteLimit = MulDiv(ulTotalByteLimit,                                            ulStreamBw, ulClipBw);                                if ((ulByteLimit == 0) &&                    (ulTotalByteLimit != 0))                {                    // Make sure all streams have a byte limit                    // if ulTotalByteLimit is non-zero. This is done                    // because a byte limit of 0 means unlimited                    // buffering is allowed                    ulByteLimit = 1;                }                pBufLimit->SetByteLimit(i, ulByteLimit);            }        }    }    HX_RELEASE(pBufLimit);}HX_RESULT HXFeedbackBufferControl::InitTesting(IUnknown* pContext){    HX_RESULT res = HXR_OK;    IHXRequest* pRequest = NULL;    const char* pURL = 0;    if (HXR_OK == pContext->QueryInterface(IID_IHXRequest,                                            (void**)&pRequest) &&        HXR_OK == pRequest->GetURL(pURL))    {        CHXURL url(pURL, pContext);                DEBUG_OUT(m_pErrMsg, DOL_BUFFER_CONTROL,                  (s, "FBBC : url %s", pURL));                IHXValues* pOptions = url.GetOptions();        ULONG32 ulTmp;                if (pOptions)        {            if (HXR_OK == pOptions->GetPropertyULONG32("FBBC-total_control",                                                       ulTmp))            {                DEBUG_OUT(m_pErrMsg, DOL_BUFFER_CONTROL,                          (s, "FBBC : total control %lu", ulTmp));                m_bControlTotal = (ulTmp > 0) ? TRUE : FALSE;            }        }                HX_RELEASE(pOptions);        HX_RELEASE(pRequest);    }    return res;}BOOL HXFeedbackBufferControl::IsBuffering(){    BOOL bRet = FALSE;    IHXBuffer* pStatusDesc = NULL;    UINT16 unStatusCode    = 0;    UINT16 unPercentDone   = 0;    if (m_pStatus &&        (HXR_OK == m_pStatus->GetStatus(unStatusCode,                                         pStatusDesc, unPercentDone)) &&        (unStatusCode == HX_STATUS_BUFFERING))    {        bRet = TRUE;    }    HX_RELEASE(pStatusDesc);    return bRet;}UINT32 HXFeedbackBufferControl::ClampBandwidth(UINT32 ulBandwidth) const{    UINT32 ulRet = ulBandwidth;    if (ulRet < m_control.Min())    {        ulRet = m_control.Min();    }    else if (ulRet > m_control.Max())    {        ulRet = m_control.Max();    }    return ulRet;}UINT32 HXFeedbackBufferControl::ControlToTotal(UINT32 ulValue){    return MulDiv(ulValue, m_ulClipBw, m_ulControlBw);}UINT32 HXFeedbackBufferControl::TotalToControl(UINT32 ulValue){    return MulDiv(ulValue, m_ulControlBw, m_ulClipBw);}UINT32 HXFeedbackBufferControl::MulDiv(UINT32 ulValue,                                        UINT32 ulMult, UINT32 ulDiv){    return (((ulValue / ulDiv) * ulMult) +            ((ulValue % ulDiv) * ulMult) / ulDiv);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -