Пример #1
0
        /// <summary>
        /// Select the next media bit rate using the minimum value from
        /// 2 criterias:
        /// <para>
        /// Condition 1) The bit rate selected must allow the buffer
        /// fullness to grow at least N times faster than the measured
        /// download bandwidth
        /// </para>
        /// <para>
        /// Condition 2) Using a fraction of the current buffer
        /// fullness, and a fraction of the past download bandwidth
        /// (network bit rate), find the highest bit rate encoding at
        /// which we can download to get as close as possible to the
        /// current target speed content download
        /// </para>
        /// <para>
        /// Condition 3) If in place, will not let the bit rate speed
        /// change be larger than 1 step
        /// </para>
        /// <para>
        /// NOTE speed content download is defined for a given stream
        /// bit rate (actually the bytes size) and network bit rate,
        /// as the amount of seconds worth of content that we can
        /// download per wall clock second
        /// </para>
        /// </summary>
        /// <param name="networkMediaInfo">the network media info to query</param>
        /// <param name="chunkDuration">the duration of the last chunk</param>
        /// <returns>the next bitrate to use</returns>
        private ulong GetNextBitRateUsingBandwidth(NetworkMediaInfo networkMediaInfo, double chunkDuration)
        {
            // If we are using a locked bit rate then our job is easy
            if (networkMediaInfo.LockedBitRate >= 0)
            {
                return networkMediaInfo.BitratesInfo[networkMediaInfo.LockedBitRate].NominalBitrate;
            }

            // Condition 1
            ulong bitRateCond1 = (ulong)(networkMediaInfo.DownloadBandwidthWindow.CurrentKernel / networkMediaInfo.RelativeContentDownloadSpeed);

            // Condition 2
            ulong bitRateCond2 = (ulong)
                (networkMediaInfo.DownloadBandwidthWindow.CurrentKernel
                *
                networkMediaInfo.BufferFullnessWindow.CurrentKernel
                *
                (sm_NetworkHeuristicsParams.DownloadBandwidthFraction *
                sm_NetworkHeuristicsParams.BufferFullnessFraction /
                chunkDuration));

            ulong bitRateFinal =
                bitRateCond2 < bitRateCond1 ? bitRateCond2 : bitRateCond1;

            // Condition 3
            ulong bitRateCond3 = ulong.MaxValue;

            // Only limit bitrate changes to one step at
            // a time (condition 3)
            if (networkMediaInfo.IsLimitBitrateSteps == true)
            {
                int bitRateIndex = networkMediaInfo.FindBitRateIndex(networkMediaInfo.PreviousBitrate) + 1;

                bitRateCond3 = networkMediaInfo.FindClosestBitrateByIndex(bitRateIndex);

                if (bitRateCond3 < bitRateFinal)
                {
                    bitRateFinal = bitRateCond3;
                }
            }

            NhTrace("INFO", networkMediaInfo.StreamId, "C1({0}):{1} C2:{2} C3:{3} final:{4}", networkMediaInfo.RelativeContentDownloadSpeed, bitRateCond1, bitRateCond2, bitRateCond3, bitRateFinal);

            return bitRateFinal;
        }
Пример #2
0
        /// <summary>
        /// When attempt to move the selected bit rate 1 step up, the
        /// condition is that at least a certain amount of time has
        /// elapsed since the last time bit rate was raised, the
        /// change happens provided the measured network trhoughput is
        /// larger than the measured media bit rate for the potential
        /// new bit rate to select, if no history exists for the
        /// target bit rate, use its nominal value
        /// </summary>
        /// <param name="networkMediaInfo">the network media info to query</param>
        /// <returns>New selected bit rate (may be the one used so far)</returns>
        private ulong AttemptImprovingBitRate(NetworkMediaInfo networkMediaInfo)
        {
            // Locked bitrate scenario is trivial
            if (networkMediaInfo.LockedBitRate >= 0)
            {
                return networkMediaInfo.BitratesInfo[networkMediaInfo.LockedBitRate].NominalBitrate;
            }

            // Try to improve bit rate. First get the elapsed time since
            // we last improved it
            double elapsedTimeSinceLastAttempt = networkMediaInfo.TotalStreamDownloaded - networkMediaInfo.PreviousAttempt;

            // Remember the previous bitrate we used
            ulong newBitRate = networkMediaInfo.PreviousBitrate;

            // Only try to improve it if our period has expired
            if (elapsedTimeSinceLastAttempt >= Configuration.Heuristics.Network.TryImprovingBitratePeriod)
            {
                // Move 1 step above the current one
                newBitRate = GetNextBitRate(networkMediaInfo, 1);

                // Are we actually better than before?
                if (newBitRate > networkMediaInfo.PreviousBitrate)
                {
                    // Get the index for the new bitrate
                    int newBitRateIndex = networkMediaInfo.FindBitRateIndex(newBitRate);

                    // Get the encoded bit rate because we need to check if
                    // the encoded bitrate for the new bitrate is higher than
                    // our bandwidth window
                    double mediaBitRate = networkMediaInfo.BitratesInfo[newBitRateIndex].EncodedBitrateWindow.CurrentKernel;

                    // We might not have any data on this media yet
                    if (mediaBitRate == 0)
                    {
                        // We don't have yet any history for this
                        // particular bit rate, use the nominal media bit
                        // rate
                        mediaBitRate = networkMediaInfo.BitratesInfo[newBitRateIndex].NominalBitrate;
                    }

                    // If our new bitrate is larger than our bandwidth window,
                    // then don't use it
                    if (mediaBitRate >= networkMediaInfo.DownloadBandwidthWindow.CurrentKernel)
                    {
                        // Don't move up as we would exceed the network
                        // capability
                        newBitRate = networkMediaInfo.PreviousBitrate;
                    }
                    else
                    {
                        // Remember the current point only if moving up
                        networkMediaInfo.PreviousAttempt = networkMediaInfo.TotalStreamDownloaded;

                        NhTrace(
                            "INFO",
                            networkMediaInfo.StreamId,
                            "mediaBitRate:{0}/{1} < downloadBandwidth:{2}, can go there",
                            newBitRate,
                            mediaBitRate,
                            networkMediaInfo.DownloadBandwidthWindow.CurrentKernel);
                    }
                }
                else
                {
                    // Apparently we weren't, so use the old one
                    newBitRate = networkMediaInfo.PreviousBitrate;
                }
            }

            return networkMediaInfo.FindClosestBitrateByValue(newBitRate);
        }