private bool busy = false; // to synchronise the non-thread-safe async WebClient...

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Create a new empty demuxer-buffer
        /// </summary>
        public mpegts_demux_buffer(PlaylistMgr Playlist)
        {
            demux = new MpegTS_Demux();
            VideoFrames = new Queue<GenericMediaFrame>();
            AudioFrames = new Queue<GenericMediaFrame>();
            playlist = Playlist;
            wc = new WebClient();
            wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
        }
        /// <summary>
        /// Start a new streaming source with a prepared playlist.
        /// This should be called in response to the Playlist's 'PlaylistReady' event.
        /// </summary>
        public HCS_MediaStreamingSource(PlaylistMgr Playlist)
        {
            playlist = Playlist;
            DemuxBuffer = new mpegts_demux_buffer(Playlist);

            DemuxBuffer.AudioSamplesAvailable += DemuxBuffer_AudioSamplesAvailable;
            DemuxBuffer.VideoSamplesAvailable += DemuxBuffer_VideoSamplesAvailable;

            StartTimer();
        }
        public void UpdatePlayhead(PlaylistMgr playlist, TimeSpan NewPosition)
        {
            if (_suspended) return;
            _playlist = playlist;
            //int chunk = (int)Math.Floor(NewPosition.TotalSeconds / ChunkDuration.TotalSeconds);
            int chunk = _playlist.GetChunkForTime(NewPosition);
            Playhead = NewPosition;

            chunk = Math.Min(AvailableChunkCount - 1, Math.Max(0, chunk));
            _lastChunk = chunk;
            MoveThumbToChunk(_lastChunk);
        }
        public void UpdatePosition(PlaylistMgr Playlist, TimeSpan CurrentPosition, MediaElementState State)
        {
            if (_isUpdating) return;
            _isUpdating = true;
            int AvailableChunkCount = Playlist.AvailableChunkCount;
            _lastTotalPlayLength = Playlist.PlaylistDuration;

            ChunkSlider.AvailableChunkCount = AvailableChunkCount;
            ChunkSlider.ChunkDuration = Playlist.ChunkDuration;

            if (CurrentPosition == TimeSpan.Zero) {
                TimeTextBox.Text = "Loading";
            } else {
                TimeTextBox.Text = State.ToString() + "  " + FormatTimeSpan(CurrentPosition);
                ChunkSlider.UpdatePlayhead(Playlist, CurrentPosition);
            }
            _isUpdating = false;
        }
        /// <summary>
        /// Prepare and start a new playlist, hooked up to the ready event.
        /// </summary>
        private void SetPlaylist(string value)
        {
            Playlist = new PlaylistMgr(value);

            Playlist.PlaylistReady += Playlist_PlaylistReady;
            Playlist.StartReading();
        }
        /// <summary>
        /// Prepare and start a new playlist, hooked up to the ready event.
        /// </summary>
        private void SetPlaylist(string value)
        {
            Playlist = new PlaylistMgr(value /*"http://www.arqiva.twofourstaging.net/hls/index.m3u8.gz"*/);

            Playlist.PlaylistReady += new EventHandler(Playlist_PlaylistReady);
            Playlist.StartReading();
        }