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(); }
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(); }
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(); }
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(); }
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(); }