示例#1
0
文件: VideoPlayer.cs 项目: slamj1/FNA
        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();
            }
        }
示例#2
0
文件: VideoPlayer.cs 项目: slamj1/FNA
        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);
        }