OpenGLPlayerPanel.java :  » Graphic-Library » apollo » org » apollo » player » Java Open Source

Java Open Source » Graphic Library » apollo 
apollo » org » apollo » player » OpenGLPlayerPanel.java
/*
 * Apollo - Motion capture and animation system
 * Copyright (c) 2005 Apollo
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * http://www.gnu.org/copyleft/gpl.html
 *
 * @author Giovane.Kuhn - brain@netuno.com.br
 *
 */
package org.apollo.player;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URL;

import javax.media.Duration;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.NoProcessorException;
import javax.media.NotConfiguredError;
import javax.media.Processor;
import javax.media.Time;
import javax.media.UnsupportedPlugInException;
import javax.media.control.FramePositioningControl;
import javax.media.control.TrackControl;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JScrollPane;

import jmapps.util.StateHelper;

import org.apollo.ApolloUtil;
import org.apollo.MediaUtil;
import org.apollo.datamodel.Video;
import org.apollo.i18n.ApolloResource;
import org.apollo.renderer.OpenGLRenderer;
import org.apollo.view.PropertyPanel;

/**
 * Panel to play a video, render with OpenGL
 * @author Giovane.Kuhn on 26/05/2005
 */
public final class OpenGLPlayerPanel extends PropertyPanel implements IPlayer {

    private static final long serialVersionUID = 1L;

    /** Video renderer */
    protected final OpenGLRenderer renderer;

    /** Thread to execute video */
    private final Animator animator;

    /** Video player */
    private Processor player;

    /** Video frame controling */
    private FramePositioningControl fpc;

    /** Video to play */
    private Video video;

    /** Label to show frame number */
    private JLabel frameLabel;

    /** Total frame on video */
    private int framesTotal;

    public OpenGLPlayerPanel() {
        this.renderer = new OpenGLRenderer(this);
        this.animator = new Animator();
        this.animator.start();
        this.add(new JScrollPane(renderer.getComponent()), REMAINDER_POSITION, 1, BOTH_RESIZABLE);
        JButton item;
        this.add(item = new JButton(ApolloResource.getText("panel.player.button.backward")), 1, 1, WIDTH_RESIZABLE);
        item.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                step(-1);
            }

        });
        this.add(item = new JButton(ApolloResource.getText("panel.player.button.start")), 1, 1, WIDTH_RESIZABLE);
        this.add(frameLabel = new JLabel(""), 1, 1, NONE_RESIZABLE);
        item.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                start();
            }

        });
        this.add(item = new JButton(ApolloResource.getText("panel.player.button.stop")), 1, 1, WIDTH_RESIZABLE);
        item.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                stop();
            }

        });
        this.add(item = new JButton(ApolloResource.getText("panel.player.button.forward")), REMAINDER_POSITION, 1, WIDTH_RESIZABLE);
        item.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                step(1);
            }

        });
    }

    /**
     * Return player video renderer
     * @return An instance of {@link org.apollo.renderer.OpenGLRenderer OpenGLRenderer}
     */
    public OpenGLRenderer getRenderer() {
        return renderer;
    }

    /** 
     * Refresh frame numbers on diplay
     */
    public void refreshDisplay() {
        frameLabel.setText((getActualFrame() + 1) + " / " + framesTotal);
        frameLabel.repaint();
    }

    public int getTotalFrames() {
        return framesTotal;
    }

    public int getActualFrame() {
        return fpc.mapTimeToFrame(player.getMediaTime());
    }

    /**
     * Step frames
     * @param frames Frame quantity to step 
     */
    public synchronized void step(int frames) {
        if (player == null || frames == 0) {
            return;
        }
        int desired = (getActualFrame() + frames) % framesTotal;
        if (desired < 0) {
            desired += framesTotal;
        }
        // skip desires frames
        fpc.skip(desired - getActualFrame());
        refreshDisplay();
    }

    /**
     * Seek informed frame
     * @param frame Frame to be sought 
     */
    public synchronized void seek(int frame) {
        if (player == null || frame < 0 || frame >= framesTotal) {
            return;
        }
        // skip desires frames
        fpc.seek(frame);
        refreshDisplay();
    }

    public void stop() {
        synchronized (animator) {
            animator.threadSuspend = true;
        }
    }

    public void start() {
        if (player == null) {
            return;
        }
        if (animator.threadSuspend) {
            synchronized (animator) {
                animator.threadSuspend = false;
                animator.notify();
            }
        }
    }

    public synchronized void close() {
        setVideo(null);
    }

    public void reset() {
        Video temp = video;
        close();
        setVideo(temp);
    }

    /**
     * Set video to be played, if informed <code>null</code> reset player.
     * If one is informed, the player leaves it video prefetched (ready to start)
     * @param video Video to played or <code>null</code> to reset player
     */
    public synchronized void setVideo(Video video) {

        if (this.video == video) {
            // video not changed
            return;
        }
        this.video = video;
        if (video == null) {
            // doesn't present any video
            stop();
            player.close();
            player = null;
            ApolloUtil.gc();
            return;
        }
        try {
            Manager.setHint(Manager.LIGHTWEIGHT_RENDERER, new Boolean(true));

            // create player
            MediaLocator locator = new MediaLocator(new URL("file", null, video.getCanonicalVideoFile()));
            player = Manager.createProcessor(locator);

            // configure processor
            StateHelper helper = new StateHelper(player);
            if (!helper.configure()) {
                throw new RuntimeException("Failed to configure the player");
            }

            // can be uses as a player.
            player.setContentDescriptor(null);

            // search the track control for the video track.
            TrackControl videoTrack = MediaUtil.getVideoTrack(player);
            if (videoTrack == null) {
                throw new RuntimeException("The input media does not contain a video track.");
            }
            videoTrack.setRenderer(renderer);

            // retrieve a FramePositioningControl from the player.
            fpc = (FramePositioningControl) player.getControl("javax.media.control.FramePositioningControl");
            if (fpc == null) {
                throw new RuntimeException("The player does not support FramePositioningControl.");
            }

            // prefetch player
            if (!helper.prefetch(30000)) {
                throw new RuntimeException("Failed to prefetch the player");
            }

            // get total frames info
            Time duration = player.getDuration();
            if (duration != Duration.DURATION_UNKNOWN) {
                framesTotal = fpc.mapTimeToFrame(duration) + 1;
            } else {
                framesTotal = FramePositioningControl.FRAME_UNKNOWN;
            }
            refreshDisplay();
        } catch (NoProcessorException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (NotConfiguredError e) {
            throw new RuntimeException(e);
        } catch (UnsupportedPlugInException e) {
            throw new RuntimeException(e);
        }
    }

    private final class Animator extends Thread {

        protected volatile boolean threadSuspend = true;

        public void run() {
            while (true) {
                try {
                    // code to suspend a thread safely
                    if (threadSuspend) {
                        synchronized (this) {
                            while (threadSuspend) {
                                wait();
                            }
                        }
                    }
                    step(1);
                    sleep((long) (1 / 25.0f * 1000));
                } catch (InterruptedException e) {
                    // nop
                }
            }
        }
    }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.