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 displayVideoFrame(VideoLib.VideoFrame videoFrame) { videoFrame.copyFrameDataTexture(yuvTexture); }