/// <summary>
        /// Create new demux from a stream
        /// </summary>
        /// <param name="stream"></param>        
        private void UpdateDemux(EncryptedStream stream)
        {
            TSDemux newDemux;
            if (_demux != null && _demux.IsMediaInfoReady )
            {
                newDemux = new TSDemux(stream, _demux, _playback.Metadata, _playback.CurrentDownloadBitrate, _bwHistory);
            }
            else
            {
                newDemux = new TSDemux(stream, _audioBuffer, _videoBuffer, _playback.Metadata, _playback.CurrentDownloadBitrate, _bwHistory);
            }

            if (_demux != null)
            {
                if (!_demux.IsMediaInfoReady)
                {
                    // If last demux has no media info ready, we are not carrying over demux parser buffers has been allocated,
                    // so make sure we discard those buffers by Flush(true)
                    _demux.Flush(true);
                    HLSTrace.WriteLine("Discard samples as last demux has no media info ready");
                }
                _demux.Dispose();
            }

            _demux = newDemux;

            while (!_demux.IsMediaInfoReady && !_demux.IsEndOfStream)
            {
                _demux.ReadChunk();
            }

            if (!_demux.IsMediaInfoReady)
                RaiseError("unable to parse stream");
        }
 /// <summary>
 /// Handler for Close command
 /// </summary>
 private void DoCloseMedia()
 {
     lock (_workQueueThreadLock)
     {
         HLSTrace.WriteLine("DoCloseMedia");
         _bwHistory.Close();
         _playback.AbortStreamDownloads();
         _isWorkQueueThreadStarted = false;
         _workQueueThread = null;
         _workQueue = null;
         _audioBuffer = null;
         _videoBuffer = null;
         _playlist = null;
         _playback = null;
         _program = null;
         if (_demux != null)
         {
             _demux.Dispose();
             _demux = null;
         }
     }
 }
        /// <summary>
        /// Handler for Seek command
        /// </summary>
        /// <param name="seekToTime"></param>
        private void DoSeek(long seekToTime)
        {
            HLSTrace.WriteLine("HLS MSS DoSeek, seek time {0} Hns", seekToTime);

            if (_noSeekYet && _noSampleRequestYet && 0 == seekToTime)
            {
                // There is no need to cancel download and start download again for the very first seek
                _noSeekYet = false;
                return;
            }
            _noSeekYet = false;

            // If a stream download is in progress using HttpWebRequest, then this call will flag
            // that request to discard its download stream. The playback impl will not
            // start any new stream download until ResumeDownloads is called. After this call,
            // no more data should be pushed into TSDemux or audio/video buffers.
            _playback.AbortStreamDownloads();
            // Clear work queue as after _playback.AbortStreamDownloads() there shouldn't be any pending NextStream work queue items
            _workQueue.Clear(WorkQueueElement.Command.NextStream);
            _isBuffering = false;
            _audioBuffer.EndOfPlayback = false;
            _videoBuffer.EndOfPlayback = false;
            ReportPendingSamples();

            // Flush and discard all data that are in the TSDemux or audio/video buffers
            _demux.Flush(false);
            _demux.Dispose();
            _demux = null;
            _audioBuffer.Flush();
            _videoBuffer.Flush();

            PlayListOverrideInfo overrideInfo = new PlayListOverrideInfo();
            overrideInfo.reason = PlayListOverrideReason.eSeek;
            overrideInfo.position = new TimeSpan(seekToTime);
            if (!OverridePlaylistIfNecessary(overrideInfo))
            {
                // This will find the .ts stream that should contain the seek point, and would
                // position the playback's stream index to point to that stream.
                _playback.FindSeekStream(seekToTime);
            }
            if (Playback.CurrentStream != null)
            {
                _audioBuffer.ResetTSRollverOffset();
            }
            _lastSeekPlaylistPosition = _playback.CurrentPosition;

            _playback.ResumeDownloads();

            // enter buffering mode right after seek
            _isBuffering = true;

            TSDemux currentTSDemux = _demux;

            if (_playback.BeginGetNextStream(new AsyncCallback(AsyncStreamCallback), _playback) == null)
                RaiseError("unable to open stream");
        }
Пример #4
0
        /// <summary>
        /// Special constructor for creating new demux for next stream in sequence
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="previousDemux"></param>
        public TSDemux(EncryptedStream stream, TSDemux previousDemux, IContainerMetadata metadata, uint bitrate, BandwidthHistory BWHistory)
        {
            if (previousDemux == null)
                throw new ArgumentNullException("previousDemux");

            CommonConstruct(stream, previousDemux._audioBuffer, previousDemux._videoBuffer, metadata, bitrate, BWHistory);

            if (!stream.Discontinuity)
                _streams = previousDemux._streams;

            _audioFormatParser = previousDemux._audioFormatParser;
            _videoFormatParser = previousDemux._videoFormatParser;
            _audioFormatParser.HLSStream = stream.HLSStream;
            _videoFormatParser.HLSStream = stream.HLSStream;
        }