×

Discussion Board

Results 1 to 6 of 6
  1. #1
    Registered User
    Join Date
    Aug 2004
    Posts
    5

    Playing back many videos with the MMAPI

    We have implemented a MIDlet that allows to browse a base of .3gp video that are available on a given server through HTTP.

    Once the video has been found, it is downloaded, saved in the RecordStore for later use, and played.

    My problem is, after the third or fourth video played in a row, the JVM explodes with an OutOfMemoryError. This happens on Nokia 3650, 3660 and 6600.

    Here is the way I'm doing things :
    - I create a new player each time, for every new video,
    - then I play the video,
    - when the user decides to close the video, I free the memory (or at least I try my best !) this way :

    private void discardPlayer() {
    if (player != null) {
    player.removePlayerListener(this);

    player.close();
    player = null;
    System.gc();

    try {
    Thread.sleep(200);
    } catch (InterruptedException e) {
    }
    }

    The sleep(200) is there to help path a known bug of garbage collection in MIDP 2.0 (Known Issues).

    Does somebody else have the same problem ? Am I doing things in a strange way ? Bugs me !

    Fabien

  2. #2
    Super Contributor
    Join Date
    Mar 2004
    Location
    Bangalore,India
    Posts
    2,146
    how and where are u calling the function discardPlayer() coz most certainly it is a memory issue and somehow the memory that yur player objects are using up is not being freed the way u want it to be.
    ciao

  3. #3
    Registered User
    Join Date
    Aug 2004
    Posts
    5
    I call the method just before I create a new player.

    Do you have an experience of using repeatedly many different video players without experiencing memory leaks ?

  4. #4
    Super Contributor
    Join Date
    Mar 2004
    Location
    Bangalore,India
    Posts
    2,146
    i havent had experience of multiple video players but yes i have used multiple audio players without any memory leaks and it worked fine for me..so m assuming there aint no diff between the audio and the video players..
    i personally think u r doing the right things...not really sure where the leaks are coming from in yur case..maybe paste yur code..and let me have a look at it..and i could suggest u something on that.
    ciao

  5. #5
    Registered User
    Join Date
    Aug 2004
    Posts
    5
    Here comes the copy-paste of the VideoCanvas.
    Thank you for your concern !

    public class VideoCanvas extends Canvas implements CommandListener, PlayerListener {

    private final /*MediaSampler*/MIDlet midlet;
    private String videoFile;

    private final Command stopCommand;
    //private final Command exitCommand;
    private final Command replayCommand;
    private final Command backCommand;

    private Player player;
    private boolean playPending = false;

    private String error;

    public VideoCanvas(/*MediaSampler*/MIDlet midlet) {
    this.midlet = midlet;

    stopCommand = new Command("Pause", Command.SCREEN, 2);
    //exitCommand = new Command("Exit", Command.EXIT, 1);
    replayCommand = new Command("Play", Command.SCREEN, 1);
    backCommand = new Command("Back", Command.SCREEN, 1);
    //addCommand(stopCommand);
    //addCommand(backCommand);
    //addCommand(exitCommand);

    setCommandListener(this);
    }

    // defer actual playing until we'reshown,see showNotify()
    public void prepareToPlay(String videoFile) {
    discardPlayer();
    this.videoFile = videoFile;
    playPending = true;
    }

    //Play video only when we'redisplayed. Use play Pending flag to
    //avoid restarting if a system screen momentarily obscures us
    public void showNotify() {
    if (playPending) {
    playPending = false;
    play();
    }
    }

    public void paint(Graphics g) {
    g.setColor(0);//black, like in a cinema !
    g.fillRect(0, 0, getWidth(), getHeight());
    //Displaying error
    if (error != null) {
    g.setColor(0xFF0000);
    g.drawString(error, 5, getHeight() - 5, Graphics.BOTTOM | Graphics.LEFT);
    }
    }

    public void commandAction(Command c, Displayable d) {
    if (c == stopCommand) {

    if (player != null) {
    try {
    player.stop();
    } catch (MediaException e) {
    stop();
    }
    }

    } else if (c == replayCommand) {

    if (player != null) {
    try {
    player.start();
    } catch (MediaException e) {
    stop();
    }
    }

    } else if (c == backCommand) {

    stop();

    }
    }

    // public void keyPressed(int keyCode) {
    // if (getGameAction(keyCode) == LEFT) {
    // stop();
    // }
    // }

    void stop() {
    discardPlayer();
    ESGController.getESGController().reload();
    }

    public void initializeContent() {

    if (videoFile == null){
    alertError("No video file specified");
    }

    try {
    //ESGController.getLogger().logln("Playing Video \"" + videoFile + "\"");

    //#ifdef LOCAL
    InputStream is = getClass().getResourceAsStream("/" + videoFile);
    //#else
    //# byte[] video_data = ResourcesManager.getBytesForResource(videoFile);
    //# if (video_data == null) {
    //# System.err.println("No data found for video " + videoFile);
    //# ESGController.getLogger().logln("No data found for video " + videoFile);
    //# return;
    //# }
    //# InputStream is = new ByteArrayInputStream(video_data);
    //#endif

    player = Manager.createPlayer(is, "video/3gpp");

    //ESGController.getLogger().logln("Player is : " + player);

    player.addPlayerListener(this);
    player.realize();

    } catch (IOException ioe) {
    discardPlayer();
    alertError("IOException:" + ioe);
    } catch (MediaException me) {
    discardPlayer();
    alertError("Media Exception : " + me);
    } catch (Throwable t) {
    alertError("Unexpected error : " + t);
    }

    }

    private void play() {

    if (player == null) return;

    try {
    //get the video control and attach it to our canvas
    VideoControl videoControl = (VideoControl) (player.getControl("VideoControl"));
    if (videoControl == null) {
    alertError("Video Control not supported");
    } else {

    videoControl.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, this);
    //centre video, letting it be clipped if it's too big
    int canvasWidth = getWidth();
    int canvasHeight = getHeight();
    int displayWidth = videoControl.getDisplayWidth();
    int displayHeight = videoControl.getDisplayHeight();
    int x = (canvasWidth - displayWidth) / 2;
    int y = (canvasHeight - displayHeight) / 2;
    videoControl.setDisplayLocation(x, y);
    videoControl.setDisplayFullScreen(true);

    videoControl.setVisible(true);
    player.start();
    }

    } catch (MediaException me) {
    discardPlayer();
    alertError("Media Exception : " + me);
    } catch (SecurityException se) {
    discardPlayer();
    alertError("SecurityException:" + se);
    } catch (IllegalArgumentException ae) {
    discardPlayer();
    alertError("No Video File Found");
    }
    }

    // Called in case of exception to make sure invalid players are closed
    private void discardPlayer() {

    if (player != null) {

    player.removePlayerListener(this);

    player.close();
    player = null;
    System.gc();

    try {
    Thread.sleep(200);
    } catch (InterruptedException e) {}

    }

    }

    public void playerUpdate(final Player p, final String event, final Object eventData) {
    //queue a call to updateEvent in the user interface event queue
    Display display = Display.getDisplay(midlet);
    display.callSerially(new Runnable() {
    public void run() {
    VideoCanvas.this.updateEvent(p, event, eventData);
    }
    });
    }

    private void updateEvent(Player p, String event, Object eventData) {
    if (event == END_OF_MEDIA) {
    addCommand(backCommand);
    addCommand(replayCommand);
    removeCommand(stopCommand);
    } else if (event == STOPPED) {
    addCommand(replayCommand);
    removeCommand(stopCommand);
    removeCommand(backCommand);
    } else if (event == STARTED) {
    removeCommand(replayCommand);
    addCommand(stopCommand);
    removeCommand(backCommand);
    }
    }

    private void alertError(String error) {
    this.error = error;
    addCommand(backCommand);
    removeCommand(stopCommand);
    removeCommand(replayCommand);
    }
    }

  6. #6
    Registered User
    Join Date
    Oct 2004
    Posts
    37
    Hi,

    I also want to store a video clip on the phone itself if user wants to save after watching it over a http connection. Please guide me in doing so.

    Any help is greatly appreciated.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×