FileDocCategorySizeDatePackage
VideoTrack.javaAPI DocFobs4JMF API 0.4.16079Wed Jan 10 11:10:10 GMT 2007com.omnividea.media.parser.video

VideoTrack.java

/******************************************************************************
* FOBS Java CrossPlatform JMF PlugIn
* Copyright (c) 2004 Omnividea Multimedia S.L
* Coded by Jose San Pedro Wandelmer
*
*    This file is part of FOBS.
*
*    FOBS is free software; you can redistribute it and/or modify
*    it under the terms of the GNU Lesser General Public License as
*    published by the Free Software Foundation; either version 2.1 
*    of the License, or (at your option) any later version.
*
*    FOBS 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 Lesser General Public License for more details.
*
*    You should have received a copy of the GNU Lesser General Public
*    License along with FOBS; if not, write to the Free Software
*    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
******************************************************************************/

/*
 * Created by Jose San Pedro Wandelmer
 * ChangeLog:
 *  Robert Hastings 2007/01/04
 *   - Native Library Location routines
 *   - Improvements to frame buffer management
 */
 
package com.omnividea.media.parser.video;

import com.omnividea.FobsConfiguration;

import javax.media.*;
import javax.media.protocol.*;
import javax.media.format.*;
import java.awt.*;
import com.sun.media.format.*;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.ByteOrder;

class VideoTrack implements javax.media.Track
{
  static private int bMask = 0x0000ff00;
  static private int gMask = 0x00ff0000;
  static private int rMask = 0xff000000;

  private VideoFormat outFormat;
  private boolean enabled = false;
  private Time startTime = new Time(0.0);
  private Time duration =  new Time(0.0);
  private Parser parser = null;
  private ByteBuffer byteBuffer = null;
  private IntBuffer intBuffer = null;
  private long timestamp = 0;
  
  private long lts = 0, lt = 0;
  private long accTime = 0;
  private int[] pixels; // Instead of newing these each time we will just keep using these

  public VideoTrack(int videoWidth, int videoHeight, float frameRate, 
                    Time duration, Time startTime, Parser parser)
  {
      /*outFormat = new RGBFormat (
      new Dimension(videoWidth,videoHeight),
      videoWidth * videoHeight, int[].class,
      frameRate,
      32,
      rMask, gMask, bMask,
      1,videoWidth,
      Format.FALSE, // flipped
      Format.NOT_SPECIFIED
      );*/
    outFormat = new AviVideoFormat(
        "ffmpeg_video",
        new Dimension(videoWidth, videoHeight),
        videoWidth * videoHeight, byte[].class,
        (float)frameRate, 0, 0, 0, 0, 0, 0, 0, new byte[0]);
 
    this.duration = duration;
    enabled = true;
    this.parser = parser;
    this.startTime = startTime;

  }
  public Format getFormat()
  {
    return outFormat;
  }
  public void setEnabled(boolean t){enabled = t;}
  public boolean isEnabled(){return enabled;}

  public Time getStartTime(){return startTime;}

  public void readFrame(Buffer buffer)
  {
    if (buffer == null)
        return;

    if (!isEnabled()) {
        buffer.setDiscard(true);
        return;
    }

    buffer.setFormat(outFormat);
    Object obj = buffer.getData();
    int[] data;
    long location;
    int needDataSize;

    /*
    if (location < minLocation) {
        buffer.setDiscard(true);
        return;
    } else if (location >= maxLocation) {
        buffer.setLength(0);
        buffer.setEOM(true);
        return;
    }
    */

    needDataSize = outFormat.getSize().width*outFormat.getSize().height;


    /*if  ( (obj == null) ||
          (! (obj instanceof int[]) ) ||
          ( ((int[])obj).length < needDataSize) ) {
        int []pixels = (int [])FobsConfiguration.properties.get("BufferedImageIntBuffer");
        if(pixels == null)
        {
            data = new int[needDataSize];
        }
        else
        {
            data  = pixels;
        }
        buffer.setData(data);
    } else {
        data = (int[]) obj;
    }*/
    
    if  ( dataNotOkay(obj, needDataSize) ) {
    	if (pixels == null) {
    		pixels = new int[needDataSize];
    	}
    	data = pixels;
        buffer.setData(data);
    } else {
        data = (int[]) obj;
    }
    
    boolean flag;
    if(FobsConfiguration.useNativeBuffers)
    {
        if(byteBuffer == null)
        {
            byteBuffer = ByteBuffer.allocateDirect(4*needDataSize);
            if(Parser.avIsBigEndian()==false) byteBuffer.order(ByteOrder.LITTLE_ENDIAN);            
        }
        //assert(byteBuffer!=null);
        flag = parser.getNextFrame(byteBuffer, 0, needDataSize);
        if(flag)
        {
            byteBuffer.asIntBuffer().get(data);
        }
    }
    else
    {
        flag = parser.getNextFrame(data, 0, needDataSize);
    }

    

    long tmp = System.currentTimeMillis();
    if(flag)
    {
        accTime += System.currentTimeMillis() - tmp;
        //System.out.println("AccTime: "+accTime);
      buffer.setOffset(0);
      buffer.setLength(needDataSize);
      //buffer.setDuration((long)(1000000000.0/outFormat.getFrameRate()));
      double videoTime = parser.getTimestamp();
      long ts = (long)((videoTime)*1000000000);
      buffer.setTimeStamp(ts);
      //System.out.println("VTS: "+ts+" Delta:"+(ts-lts)/1000000+" T:"+(tmp-lt));
      lts = ts;
      lt = tmp;
    }
    else
    {
        buffer.setLength(0);
        buffer.setEOM(true);
    }
  }

  private boolean dataNotOkay(Object obj, int needDataSize) {
	return (obj == null) ||
	      (! (obj instanceof int[]) ) ||
	      ( ((int[])obj).length < needDataSize);
  }

  public int mapTimeToFrame(Time t){
	  System.out.println("FobsVideoTrack: mapTimeToFrame");
    return 0;
  }
  public Time mapFrameToTime(int frameNumber){
	  System.out.println("FobsVideoTrack: mapFrameToTime");
    return null;
  }

  public void setTrackListener(TrackListener listener){}
  public Time getDuration(){return parser.getDuration();}

}