private void OnBufferRequest(object sender, EventArgs args) { int samples = Theorafile.tf_readaudio( Video.theora, audioDataPtr, AUDIO_BUFFER_SIZE ); if (samples > 0) { audioStream.SubmitFloatBufferEXT( audioData, 0, samples ); } else if (Theorafile.tf_eos(Video.theora) == 1) { // Okay, we ran out. No need for this! audioStream.BufferNeeded -= OnBufferRequest; } }
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); }