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;
        }
Exemple #2
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);
        }