/// <summary>
        /// Waits for the frame extractor to be ready for playback.
        /// Returns true if successful, false if it timed out.
        /// </summary>
        private bool WaitForPlaybackReadyState()
        {
            var renderTime = RealtimeClock.PositionSeconds;
            var startTime  = DateTime.UtcNow;
            var cycleCount = -1;
            FFmpegMediaFrame playbackFrame = null;

            while (IsCancellationPending == false)
            {
                if (DateTime.UtcNow.Subtract(startTime) > Constants.WaitForPlaybackReadyStateTimeout)
                {
                    ErrorOccurredCallback(this, new MediaPlaybackException(MediaPlaybackErrorSources.WaitForPlaybackReadyState,
                                                                           MediaPlaybackErrorCode.WaitForPlaybackTimedOut,
                                                                           string.Format("Waiting for playback ready state @ {0:0.000} rimed Out in {1} cycles", renderTime, cycleCount)));
                    return(false);
                }

                cycleCount++;

                // Wait for a decoding cycle.
                MediaFramesExtractedDone.Wait(Constants.FrameExtractorWaitMs);
                renderTime    = RealtimeClock.PositionSeconds;
                playbackFrame = LeadingFramesCache.GetFrame(renderTime, CheckFrameBounds);

                if (IsLiveStream && LeadingFramesCache.Count > 0)
                {
                    playbackFrame = LeadingFramesCache.FirstFrame;
                    break;
                }

                if (playbackFrame != null)
                {
                    break;
                }
            }

            // Do some additional logging
            System.Diagnostics.Debug.WriteLineIf(
                cycleCount >= 0,
                string.Format("WaitForPlaybackReadyState @ {0:0.000} = {1} cycles. Leading Frames: {2}, Frame Index: {3}, Frame Start: {4}",
                              renderTime,
                              cycleCount,
                              LeadingFramesCache.Count,
                              LeadingFramesCache.IndexOf(playbackFrame),
                              (playbackFrame != null ?
                               playbackFrame.StartTime.ToString("0.000") : "NULL")));

            return(true);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Releases all managed and unmanaged resources
        /// </summary>
        public void Dispose()
        {
            if (IsCancellationPending)
            {
                return;
            }

            this.IsCancellationPending = true;

            this.VideoRenderTimer.Stop();

            if (this.AudioRenderer != null)
            {
                if (this.AudioRenderer.HasInitialized)
                {
                    this.AudioRenderer.Stop();
                }

                this.AudioRenderer.Dispose();
                this.AudioRenderer = null;
            }

            if (MediaFrameExtractorThread != null)
            {
                MediaFrameExtractorThread.Join();
                MediaFrameExtractorThread = null;
            }

            if (MediaFramesExtractedDone != null)
            {
                try
                {
                    MediaFramesExtractedDone.Dispose();
                    MediaFramesExtractedDone = null;
                }
                finally { }
            }

            if (LeadingFramesCache != null)
            {
                LeadingFramesCache.Clear();
                LeadingFramesCache = null;
            }

            if (LaggingFramesCache != null)
            {
                LaggingFramesCache.Clear();
                LaggingFramesCache = null;
            }

            if (VideoCodecContext != null)
            {
                fixed(AVCodecContext **videoCodecContextRef = &VideoCodecContext)
                {
                    ffmpeg.avcodec_close(VideoCodecContext);
                    ffmpeg.avcodec_free_context(videoCodecContextRef);
                    VideoCodecContext = null;
                }
            }

            if (AudioCodecContext != null)
            {
                fixed(AVCodecContext **audioCodecContextRef = &AudioCodecContext)
                {
                    ffmpeg.avcodec_close(AudioCodecContext);
                    ffmpeg.avcodec_free_context(audioCodecContextRef);
                    AudioCodecContext = null;
                }
            }

            if (VideoResampler != null)
            {
                ffmpeg.sws_freeContext(VideoResampler);
                VideoResampler = null;
            }

            if (AudioResampler != null)
            {
                fixed(SwrContext **audioResamplerRef = &AudioResampler)
                {
                    ffmpeg.swr_close(AudioResampler);
                    ffmpeg.swr_free(audioResamplerRef);
                    AudioResampler = null;
                }
            }

            if (InputFormatContext != null)
            {
                fixed(AVFormatContext **inputFormatContextRef = &InputFormatContext)
                {
                    ffmpeg.avformat_close_input(inputFormatContextRef);
                    ffmpeg.avformat_free_context(InputFormatContext);
                    InputFormatContext = null;
                }
            }

            if (DecodedPictureHolder != null)
            {
                ffmpeg.av_free(DecodedPictureHolder);
                DecodedPictureHolder = null;
            }

            if (DecodedWaveHolder != null)
            {
                ffmpeg.av_free(DecodedWaveHolder);
                DecodedWaveHolder = null;
            }
        }