public TimelineTrackingInfo(int timelindeIndex, long startTimeStampHNS, long endTimeStampHNS, TimelineTrackingInfo previousTimelineInfo)
 {
     currentTimelineIndex = timelindeIndex;
     timelineStartTimeStampHNS = startTimeStampHNS;
     timelineEndTimeStampHNS = endTimeStampHNS;
     previousTimeline = previousTimelineInfo;
 }
 public void EstablishTimeline(List<TimeLineInfo> timelineInfoList)
 {
     lock (this)
     {
         _timelineInfoList = timelineInfoList;
         _timelineTrackingInfo = null;
     }
 }
        /// <summary>
        /// Produces next sample to play.
        /// </summary>
        /// <returns></returns>
        private Sample DequeueSample()
        {
            Sample sample = null;

            lock (this)
            {
                if (_samples.Count == 0)
                    return null;

                sample = _samples.Dequeue();

                _totalSizeOfSamples -= (int)sample.DataStream.Length;
                _bufferLevel -= sample.Duration;

                if (sample == _lastSample)
                    _lastSample = null;

                HLSTrace.WriteLineLow("DequeueSample from {0} to {1} timeline {2}", sample.Timestamp / ConvertHelper.MSInHNS, sample.AdjustedTimeStamp / ConvertHelper.MSInHNS, sample.TimelineIndex);

                if (null == _timelineTrackingInfo)
                {
                    _timelineTrackingInfo = new TimelineTrackingInfo(sample.TimelineIndex, sample.AdjustedTimeStamp, sample.AdjustedTimeStamp, null);
                }
                else
                {
                    if (sample.TimelineIndex != _timelineTrackingInfo.currentTimelineIndex)
                    {
                        _timelineTrackingInfo.previousTimeline = new TimelineTrackingInfo(_timelineTrackingInfo.currentTimelineIndex, _timelineTrackingInfo.timelineStartTimeStampHNS, _timelineTrackingInfo.timelineEndTimeStampHNS, null);
                        _timelineTrackingInfo.currentTimelineIndex = sample.TimelineIndex;
                        _timelineTrackingInfo.timelineStartTimeStampHNS = sample.AdjustedTimeStamp;
                        _timelineTrackingInfo.timelineEndTimeStampHNS = sample.AdjustedTimeStamp;
                    }
                    else
                    {
                        _timelineTrackingInfo.timelineEndTimeStampHNS = sample.AdjustedTimeStamp;
                    }
                }
            }

            return sample;
        }
        /// <summary>
        /// Adds a new sample to the buffer.
        /// </summary>
        /// <param name="sample"></param>
        public void Enqueue(Sample sample)
        {
            lock (this)
            {
                Debug.Assert(_timelineInfoList.Count > sample.TimelineIndex);

                if (-1 == _timelineInfoList[sample.TimelineIndex]._timelineStartOffsetHNS)
                {
                    sample.AdjustedTimeStamp = sample.Timestamp;
                }
                else
                {
                    if (-1 == _timelineInfoList[sample.TimelineIndex]._timelineStartTimeStamp)
                    {
                        _timelineInfoList[sample.TimelineIndex]._timelineStartTimeStamp = sample.Timestamp;
                        sample.AdjustedTimeStamp = _timelineInfoList[sample.TimelineIndex]._timelineStartOffsetHNS;
                    }
                    else
                    {
                        sample.AdjustedTimeStamp = sample.Timestamp - _timelineInfoList[sample.TimelineIndex]._timelineStartTimeStamp + _timelineInfoList[sample.TimelineIndex]._timelineStartOffsetHNS;
                    }
                }

                if (null == _timelineTrackingInfo)
                {
                    _timelineTrackingInfo = new TimelineTrackingInfo(sample.TimelineIndex, sample.AdjustedTimeStamp, sample.AdjustedTimeStamp, null);
                }
                _timelineTrackingInfo.lastTimeStamp = sample.Timestamp;
                _timelineTrackingInfo.lastAdjustedTimeStamp = sample.AdjustedTimeStamp;
                _samples.Enqueue(sample);
                _totalSizeOfSamples += (int)sample.DataStream.Length;
                _bufferLevel += sample.Duration;
                _lastSample = sample;
                if (_hnsSegmentStart == -1 )
                {
                    _hnsSegmentStart = sample.AdjustedTimeStamp;
                }

                SegmentProgramDateTime segmentTime =sample.HLSStream.SegmentProgramTime;
                if ( segmentTime!= null && segmentTime.programTime.TsStartTime == DateTime.MinValue)
                {
                    segmentTime.programTime.TsStartTime = segmentTime.programTime.startTime + segmentTime.offset - TimeSpan.FromTicks(sample.AdjustedTimeStamp);
                }
            }

            HLSTrace.WriteLineLow("Enqueue sample timestamp {0} adjust to {1}, size {2}, timeline {3}", sample.Timestamp / ConvertHelper.MSInHNS, sample.AdjustedTimeStamp / ConvertHelper.MSInHNS, sample.DataStream.Length, sample.TimelineIndex);
        }