Esempio n. 1
0
        private TimeSpan CalculateDownloadTimeout(Segment segment)
        {
            if (!IsDynamic)
            {
                return(TimeSpan.MaxValue);
            }
            var timeout           = timeBufferDepthDefault;
            var averageThroughput = throughputHistory.GetAverageThroughput();

            if (averageThroughput > 0 && currentRepresentation.Bandwidth.HasValue && segment.Period != null)
            {
                var bandwidth            = currentRepresentation.Bandwidth.Value;
                var duration             = segment.Period.Duration.TotalSeconds;
                var segmentSize          = bandwidth * duration;
                var calculatedTimeNeeded = TimeSpan.FromSeconds(segmentSize / averageThroughput * 1.5);
                var docParams            = currentStreams.GetDocumentParameters();
                if (docParams == null)
                {
                    throw new ArgumentNullException("currentStreams.GetDocumentParameters() returns null");
                }
                var manifestMinBufferDepth =
                    docParams.Document.MinBufferTime ?? TimeSpan.Zero;
                timeout = calculatedTimeNeeded > manifestMinBufferDepth ? calculatedTimeNeeded : manifestMinBufferDepth;
            }

            return(timeout);
        }
Esempio n. 2
0
        /// <summary>
        /// Swaps updated representation based on Manifest Reload.
        /// Updates segment information and base segment ID for the stream.
        /// </summary>
        /// <returns>bool. True. Representations were swapped. False otherwise</returns>
        private void SwapRepresentation()
        {
            // Exchange updated representation with "null". On subsequent calls, this will be an indication
            // that there is no new representations.
            var newRep = Interlocked.Exchange(ref newRepresentation, null);

            // Update internals with new representation if exists.
            if (newRep == null)
            {
                return;
            }

            initStreamBytes.Clear();

            currentRepresentation = newRep;
            currentStreams        = currentRepresentation.Segments;
            var docParams = currentStreams.GetDocumentParameters();

            if (docParams == null)
            {
                throw new ArgumentNullException("currentStreams.GetDocumentParameters() returns null");
            }

            currentStreamDuration = IsDynamic
                ? docParams.Document.MediaPresentationDuration
                : currentStreams.Duration;

            if (lastDownloadSegmentTimeRange == null)
            {
                currentSegmentId  = currentRepresentation.Segments.StartSegmentId();
                firstSegmentClock = currentStreams.SegmentTimeRange(currentSegmentId).Start;
                LogInfo($"Rep. Swap. Start Seg: [{currentSegmentId}]");
                return;
            }

            var    newSeg = currentStreams.NextSegmentId(lastDownloadSegmentTimeRange.Start);
            string message;

            if (newSeg.HasValue)
            {
                var segmentTimeRange = currentStreams.SegmentTimeRange(newSeg);
                message = $"Updated Seg: [{newSeg}]/({segmentTimeRange?.Start}-{segmentTimeRange?.Duration})";
            }
            else
            {
                message = "Not Found. Setting segment to null";
            }

            LogInfo(
                $"Rep. Swap. Last Seg: {currentSegmentId}/{lastDownloadSegmentTimeRange.Start}-{lastDownloadSegmentTimeRange.Duration} {message}");
            currentSegmentId = newSeg;

            LogInfo("Representations swapped.");
        }
Esempio n. 3
0
        public void Start(bool initReloadRequired)
        {
            SwapRepresentation();

            if (currentRepresentation == null)
            {
                throw new Exception("currentRepresentation has not been set");
            }

            initInProgress   = true;
            initDataDuration = currentStreams.GetDocumentParameters().Document.MinBufferTime ??
                               MinimumBufferTime;
            initSegmentReloadRequired = initReloadRequired;

            LogInfo("DashClient start: " + dataRequest.Duration);

            if (cancellationTokenSource == null || cancellationTokenSource?.IsCancellationRequested == true)
            {
                cancellationTokenSource?.Dispose();
                cancellationTokenSource = new CancellationTokenSource();
            }

            bufferTime = currentTime;

            if (currentSegmentId.HasValue == false)
            {
                currentSegmentId = currentRepresentation.AlignedStartSegmentID;
            }

            if (!trimOffset.HasValue)
            {
                trimOffset = currentRepresentation.AlignedTrimOffset;
            }

            if (currentStreams.InitSegment == null)
            {
                initInProgress = false;
            }

            downloadCompletedSubject.OnNext(Unit.Default);
        }