public void UpdateVideo(float elapsedFrameTime) { while (_currentVideo.playms <= elapsedFrameTime && TheoraPlay.THEORAPLAY_availableVideo(_theoraDecoder) != 0) { _currentVideo = _nextVideo; var nextFrame = TheoraPlay.THEORAPLAY_getVideo(_theoraDecoder); if (nextFrame != IntPtr.Zero) { TheoraPlay.THEORAPLAY_freeVideo(_previousFrame); _previousFrame = _videoStream; _videoStream = nextFrame; _nextVideo = GetVideoFrame(_videoStream); } } IsFinished = TheoraPlay.THEORAPLAY_isDecoding(_theoraDecoder) == 0; }
public Texture2D GetTexture() { checkDisposed(); if (Video == null) { throw new InvalidOperationException(); } // Be sure we can even get something from TheoraPlay... if (State == MediaState.Stopped || Video.theoraDecoder == IntPtr.Zero || TheoraPlay.THEORAPLAY_isInitialized(Video.theoraDecoder) == 0 || TheoraPlay.THEORAPLAY_hasVideoStream(Video.theoraDecoder) == 0) { // Screw it, give them the old one. return(videoTexture[0].RenderTarget as Texture2D); } // Get the latest video frames. bool hasFrames = true; while (nextVideo.playms <= timer.ElapsedMilliseconds && hasFrames) { currentVideo = nextVideo; hasFrames = TheoraPlay.THEORAPLAY_availableVideo(Video.theoraDecoder) > 0; if (hasFrames) { IntPtr nextFrame = TheoraPlay.THEORAPLAY_getVideo(Video.theoraDecoder); TheoraPlay.THEORAPLAY_freeVideo(previousFrame); previousFrame = Video.videoStream; Video.videoStream = nextFrame; nextVideo = TheoraPlay.getVideoFrame(Video.videoStream); } } // Check for the end... if (TheoraPlay.THEORAPLAY_isDecoding(Video.theoraDecoder) == 0) { // FIXME: This is part of the Duration hack! if (Video.needsDurationHack) { Video.Duration = new TimeSpan(0, 0, 0, 0, (int)currentVideo.playms); } // Stop and reset the timer. If we're looping, the loop will start it again. timer.Stop(); timer.Reset(); // Kill whatever audio/video we've got if (audioStream != null) { audioStream.Stop(); audioStream.Dispose(); audioStream = null; } TheoraPlay.THEORAPLAY_freeVideo(previousFrame); Video.AttachedToPlayer = false; Video.Dispose(); // If looping, go back to the start. Otherwise, we'll be exiting. if (IsLooped && State == MediaState.Playing) { // Starting over! Video.AttachedToPlayer = true; InitializeTheoraStream(); // Start! Again! timer.Start(); if (audioStream != null) { audioStream.Play(); } } else { // We out, give them the last frame. State = MediaState.Stopped; return(videoTexture[0].RenderTarget as Texture2D); } } // Set up an environment to muck about in. GL_pushState(); // Prepare YUV GL textures with our current frame data currentDevice.GLDevice.SetTextureData2DPointer( yuvTextures[0], currentVideo.pixels ); currentDevice.GLDevice.SetTextureData2DPointer( yuvTextures[1], new IntPtr( currentVideo.pixels.ToInt64() + (currentVideo.width * currentVideo.height) ) ); currentDevice.GLDevice.SetTextureData2DPointer( yuvTextures[2], new IntPtr( currentVideo.pixels.ToInt64() + (currentVideo.width * currentVideo.height) + (currentVideo.width / 2 * currentVideo.height / 2) ) ); // Draw the YUV textures to the framebuffer with our shader. currentDevice.DrawPrimitives( PrimitiveType.TriangleStrip, 0, 2 ); // Clean up after ourselves. GL_popState(); // Finally. return(videoTexture[0].RenderTarget as Texture2D); }