public void Play(Video video) { checkDisposed(); // We need to assign this regardless of what happens next. Video = video; // FIXME: This is a part of the Duration hack! if (Video.needsDurationHack) { Video.Duration = TimeSpan.MaxValue; } // Check the player state before attempting anything. if (State != MediaState.Stopped) { return; } // Update the player state now, before initializing State = MediaState.Playing; // Carve out YUV buffer before doing any decoder work if (yuvData != IntPtr.Zero) { Marshal.FreeHGlobal(yuvData); } yuvData = Marshal.AllocHGlobal( (Video.yWidth * Video.yHeight) + (Video.uvWidth * Video.uvHeight * 2) ); // Hook up the decoder to this player InitializeTheoraStream(); // Set up the texture data if (Theorafile.tf_hasvideo(Video.theora) == 1) { // The VideoPlayer will use the GraphicsDevice that is set now. if (currentDevice != Video.GraphicsDevice) { GL_dispose(); currentDevice = Video.GraphicsDevice; GL_initialize(); } RenderTargetBinding overlap = videoTexture[0]; videoTexture[0] = new RenderTargetBinding( new RenderTarget2D( currentDevice, Video.yWidth, Video.yHeight, false, SurfaceFormat.Color, DepthFormat.None, 0, RenderTargetUsage.PreserveContents ) ); if (overlap.RenderTarget != null) { overlap.RenderTarget.Dispose(); } GL_setupTextures( Video.yWidth, Video.yHeight, Video.uvWidth, Video.uvHeight ); } // The player can finally start now! timer.Start(); if (audioStream != null) { audioStream.Play(); } }
public Texture2D GetTexture() { checkDisposed(); if (Video == null) { throw new InvalidOperationException(); } // Be sure we can even get something from Theorafile... if (State == MediaState.Stopped || Video.theora == IntPtr.Zero || Theorafile.tf_hasvideo(Video.theora) == 0) { // Screw it, give them the old one. return(videoTexture[0].RenderTarget as Texture2D); } int thisFrame = (int)(timer.Elapsed.TotalMilliseconds / (1000.0 / Video.fps)); if (thisFrame > currentFrame) { // Only update the textures if we need to! if (Theorafile.tf_readvideo( Video.theora, yuvData, thisFrame - currentFrame ) == 1 || currentFrame == -1) { UpdateTexture(); } currentFrame = thisFrame; } // Check for the end... bool ended = Theorafile.tf_eos(Video.theora) == 1; if (audioStream != null) { ended &= audioStream.PendingBufferCount == 0; } if (ended) { // FIXME: This is part of the Duration hack! if (Video.needsDurationHack) { Video.Duration = timer.Elapsed; // FIXME: Frames * FPS? -flibit } // 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; } // Reset the stream no matter what happens next Theorafile.tf_reset(Video.theora); // If looping, go back to the start. Otherwise, we'll be exiting. if (IsLooped) { // Starting over! InitializeTheoraStream(); // Start! Again! timer.Start(); if (audioStream != null) { audioStream.Play(); } } else { // We out State = MediaState.Stopped; } } // Finally. return(videoTexture[0].RenderTarget as Texture2D); }