예제 #1
0
        void processVideoFrame()
        {
            bool skipVideoFrame = false;

restartvideo:

            double actualDelay = 0.04;

            Rectangle scaledVideoRec = ImageUtils.stretchRectangle(
                new Rectangle(0, 0, videoDecoder.Width, videoDecoder.Height),
                videoRender.Canvas);

            Rectangle canvas = ImageUtils.centerRectangle(videoRender.Canvas,
                                                          scaledVideoRec);

            // grab a decoded frame, returns false if the queue is stopped
            VideoFrame videoFrame = videoDecoder.FrameQueue.getDecodedVideoFrame();

            if (VideoState == VideoState.CLOSED && videoFrame == null)
            {
                return;
            }
            else if (VideoState == VideoState.PLAYING)
            {
                videoPts      = videoFrame.Pts;
                videoPtsDrift = videoFrame.Pts + HRTimer.getTimestamp();

                if (skipVideoFrame == false)
                {
                    videoRender.display(videoFrame, canvas, Color.Black, VideoRender.RenderMode.NORMAL);
                    videoDebug.VideoFrames = videoDebug.VideoFrames + 1;
                }

                actualDelay = synchronizeVideo(videoPts);
            }
            else if (VideoState == VideoState.PAUSED)
            {
                videoRender.display(null, canvas, Color.Black, VideoRender.RenderMode.PAUSED);
            }

            // do not update ui elements on main thread inside videoStateLock
            // or we can get a deadlock
            videoDebug.update();
            updateUI();

            if (actualDelay < 0.010)
            {
                // delay is too small skip next frame
                skipVideoFrame = true;
                videoDebug.NrVideoFramesDropped = videoDebug.NrVideoFramesDropped + 1;
                goto restartvideo;
            }

            // start timer with delay for next frame
            videoRefreshTimer.Interval = (int)(actualDelay * 1000 + 0.5);
            videoRefreshTimer.start();
        }
예제 #2
0
        void videoRefreshTimer_Tick(Object sender, EventArgs e)
        {
            bool skipVideoFrame = false;

restartvideo:

            double actualDelay = 0.04;

            // grab a decoded frame, returns false if the queue is stopped
            VideoLib.VideoFrame videoFrame = videoDecoder.FrameQueue.getDecodedVideoFrame();

            if (VideoState == VideoState.CLOSED && videoFrame == null)
            {
                return;
            }
            else if (VideoState == VideoState.PLAYING)
            {
                videoPts      = videoFrame.Pts;
                videoPtsDrift = videoFrame.Pts + HRTimer.getTimestamp();

                if (skipVideoFrame == false && displayVideoFrameCallback != null)
                {
                    displayVideoFrameCallback(videoFrame);
                }

                actualDelay = synchronizeVideo(videoPts);
            }
            else if (VideoState == VideoState.PAUSED)
            {
                //videoRender.display(null, canvas, Color.Black, VideoRender.RenderMode.PAUSED);
            }

            updateObservableVariables();

            if (actualDelay < 0.010)
            {
                // delay is too small skip next frame
                skipVideoFrame = true;
                //videoDebug.NrVideoFramesDropped = videoDebug.NrVideoFramesDropped + 1;
                goto restartvideo;
            }

            // start timer with delay for next frame
            videoRefreshTimer.Interval = (int)(actualDelay * 1000 + 0.5);
            videoRefreshTimer.start();
        }
예제 #3
0
        void processAudioFrame()
        {
restartaudio:

            AudioFrame audioFrame = videoDecoder.FrameQueue.getDecodedAudioFrame();

            if (audioFrame == null)
            {
                return;
            }

            videoDebug.AudioFrames      = videoDebug.AudioFrames + 1;
            videoDebug.AudioFrameLength = audioFrame.Length;

            // if the audio is lagging behind too much, skip the buffer completely
            double diff = getVideoClock() - audioFrame.Pts;

            if (diff > 0.2 && diff < 3 && syncMode == SyncMode.AUDIO_SYNCS_TO_VIDEO)
            {
                log.Warn("dropping audio buffer, lagging behind: " + (getVideoClock() - audioFrame.Pts).ToString() + " seconds");
                goto restartaudio;
            }

            //adjustAudioSamplesPerSecond(audioFrame);
            adjustAudioLength(audioFrame);

            audioPlayer.write(audioFrame);

            int frameLength = audioFrame.Length;

            double actualDelay = synchronizeAudio(frameLength);

            if (actualDelay < 0)
            {
                // delay too small, play next frame as quickly as possible
                videoDebug.NrAudioFramesLaggingBehind = videoDebug.NrAudioFramesLaggingBehind + 1;
                goto restartaudio;
            }

            // start timer with delay for next frame
            audioRefreshTimer.Interval = (int)(actualDelay * 1000 + 0.5);
            audioRefreshTimer.start();
        }
예제 #4
0
        void audioRefreshTimer_Tick(Object sender, EventArgs e)
        {
restartaudio:

            double actualDelay = 0.04;

            if (!videoDecoder.HasVideo)
            {
                updateObservableVariables();
            }

            // returns null when framequeue is paused or closed
            VideoLib.AudioFrame audioFrame = videoDecoder.FrameQueue.getDecodedAudioFrame();
            if (audioFrame == null)
            {
                // stop audio if playing
                audioPlayer.stop();

                if (VideoState == VideoState.CLOSED)
                {
                    audioPlayer.flush();
                    return;
                }
                // when paused spin idle
            }
            else
            {
                if (audioPlayer.Status == SharpDX.DirectSound.BufferStatus.None)
                {
                    // reset audio frame timer before (re)starting playing
                    audioFrameTimer = videoFrameTimer = HRTimer.getTimestamp();
                }

                audioPts = audioFrame.Pts;
                audioDts = audioFrame.Dts;

                // if the audio is lagging behind too much, skip the buffer completely
                double diff = getVideoClock() - audioFrame.Pts;
                if (diff > 0.2 && diff < 3 && syncMode == SyncMode.AUDIO_SYNCS_TO_VIDEO)
                {
                    //log.Warn("dropping audio buffer, lagging behind: " + (getVideoClock() - audioFrame.Pts).ToString() + " seconds");
                    goto restartaudio;
                }

                //adjustAudioSamplesPerSecond(audioFrame);
                adjustAudioLength(audioFrame);

                audioPlayer.play(audioFrame);

                int frameLength = audioFrame.Length;

                actualDelay = synchronizeAudio(frameLength);

                if (actualDelay < 0)
                {
                    // delay too small, play next frame as quickly as possible
                    goto restartaudio;
                }
            }

            // start timer with delay for next frame
            audioRefreshTimer.Interval = (int)(actualDelay * 1000 + 0.5);
            audioRefreshTimer.start();
        }
예제 #5
0
        void videoRefreshTimer_Tick(Object sender, EventArgs e)
        {
            bool skipVideoFrame = false;

restartvideo:

            double actualDelay = 0.04;

            // grab a decoded frame, returns null if the queue is paused or closed
            VideoFrame videoFrame = videoDecoder.FrameQueue.getDecodedVideoFrame();

            if (videoFrame == null)
            {
                if (VideoState == VideoState.CLOSED)
                {
                    videoRender.display(null, Color.Black, RenderMode.CLEAR_SCREEN);
                    videoRender.releaseResources();
                    return;
                }

                videoRender.display(null, Color.Black, RenderMode.PAUSED);
            }
            else
            {
                if (videoRender.RenderMode == RenderMode.PAUSED)
                {
                    // reset videoFrameTimer before (re)starting rendering
                    audioFrameTimer = videoFrameTimer = HRTimer.getTimestamp();
                }

                videoPts      = videoFrame.Pts;
                videoDts      = videoFrame.Dts;
                videoPtsDrift = videoFrame.Pts + HRTimer.getTimestamp();

                if (skipVideoFrame == false)
                {
                    videoRender.display(videoFrame, Color.Black, RenderMode.NORMAL);
                }

                actualDelay = synchronizeVideo(videoPts);

                NrFramesRendered++;
                framePts = videoFrame.FramePts;
                //frameDts = videoFrame.FrameDts;
                isKeyFrame = videoFrame.IsKey;
            }

            updateObservableVariables();

            if (actualDelay < 0.010)
            {
                // delay is too small skip next frame
                skipVideoFrame = true;
                NrFramesDropped++;

                goto restartvideo;
            }

            // start timer with delay for next frame
            videoRefreshTimer.Interval = (int)(actualDelay * 1000 + 0.5);
            videoRefreshTimer.start();
        }