FileDocCategorySizeDatePackage
JavaDecoder.javaAPI DocFobs4JMF API 0.4.18925Wed Jan 10 11:08:22 GMT 2007com.omnividea.media.codec.audio

JavaDecoder.java

/******************************************************************************
* FOBS Java JMF Stand Alone Codec - Java Part
* 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
 */
 
package com.omnividea.media.codec.audio;

import javax.media.*;
import javax.media.format.*;
import javax.media.format.*;
import com.sun.media.*;
import com.sun.media.format.*;
import com.sun.media.controls.*;
import com.ibm.media.codec.audio.*;
import java.awt.Dimension;
import javax.media.rtp.*;
import javax.media.control.*;
import java.awt.*;
import java.awt.event.*;
import com.moesol.bindings.NativeLibraryFinder;


/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: </p>
 * @author not attributable
 * @version 1.0
 */

public class JavaDecoder extends AudioCodec {

  //Native Methods
  private native static boolean isBigEndian();
  private native void    init();
  private native boolean open_codec(int peer, String codec);
  private native boolean close_codec(int peer);
  private native void init_decoding(int peer, int width, int height);
  private native boolean convert( int peer,
                                  Object inData, long inDataBytes, int inOffset,
                                  Object outData,  long outDataBytes, long length, double dts);
  private native int lastAudioSize(int peer);

  private int peer = 0;
  private boolean outputDone = false;


  static final private boolean DEBUG = false;
  static private boolean bigEndian = true;

  ////////////////////////////////////////////////////////////////////////////
  // Variables

  static {
    try {
      //System.loadLibrary("fobs4jmf");
      NativeLibraryFinder.loadLibrary(JavaDecoder.class, "fobs4jmf");
      System.out.println("Fobs4JMF - Native shared library found");
      bigEndian = isBigEndian();

      if(bigEndian == false)
      {
        System.out.println("Little Endian");
      }
      else
      {
          System.out.println("Big Endian");
      }

    }
    catch (UnsatisfiedLinkError e) {
      System.out.println("Fobs4JMF - Native shared library NOT found");
      e.printStackTrace();
      throw new ExceptionInInitializerError(e.getMessage());
    }
  }


  public JavaDecoder() {
    System.out.println("AVCODEC: Constructor");
    supportedInputFormats = new AudioFormat[] {
        new AudioFormat("twos"), 
        new AudioFormat("raw "), 
        new AudioFormat("ulaw"), 
        new AudioFormat("alaw"), 
        new AudioFormat("ima4"), 
        new AudioFormat("MAC3"), 
        new AudioFormat("MAC6"), 
        new AudioFormat(".mp3"), 
        new AudioFormat("mp4a"), 
        new AudioFormat("samr"), 
        new AudioFormat("sawb"), 
        new AudioFormat("alac")
    };
    defaultOutputFormats = new AudioFormat[] {
        new WavAudioFormat("")};
    PLUGIN_NAME = "Fobs Audio Decoder";

  }

  protected Format[] getMatchingOutputFormats(Format in) {
    System.out.println("AVCODEC: getMatchingOutputFormats");

       if (in == null)
           return new Format[] { new AudioFormat(AudioFormat.LINEAR) };

       AudioFormat af =(AudioFormat) in;

       supportedOutputFormats = new AudioFormat[] {
           new WavAudioFormat(AudioFormat.LINEAR,
                              af.getSampleRate(),
                              af.getSampleSizeInBits(),
                              af.getChannels(),
                              af.getFrameSizeInBits(),
                              (int)(af.getFrameSizeInBits() * af.getSampleRate()/8.0),
                              af.getEndian(),
                              af.getSigned(),
                              (float)af.getFrameRate(), // No FRAME_RATE specified
                              af.getDataType(),
                              new byte[0])
       };

    
    return supportedOutputFormats;
  }



  /**
   * Set the data input format.
   * @return false if the format is not supported.
   */
  public Format setInputFormat(Format format) {
    System.out.println("AVCODEC: setInputFormat");
      if (super.setInputFormat(format) != null) {

        AudioFormat af =(AudioFormat)format;

        outputFormat =            new WavAudioFormat(AudioFormat.LINEAR,
                              af.getSampleRate(),
                              af.getSampleSizeInBits(),
                              af.getChannels(),
                              af.getFrameSizeInBits(),
                              (int)(af.getFrameSizeInBits() * af.getSampleRate()/8.0),
                              af.getEndian(),
                              af.getSigned(),
                              (float)af.getFrameRate(), // No FRAME_RATE specified
                              af.getDataType(),
                              new byte[0]);

        return format;
    }
    else
      return null;
  }

    public void open() throws ResourceUnavailableException {
      System.out.println("AVCODEC: open");
      init();
      if (peer == 0)
          throw new ResourceUnavailableException("Unable to initialize");


      if (inputFormat == null)
          throw new ResourceUnavailableException("No input format selected");

      if (outputFormat == null)
          throw new ResourceUnavailableException("No output format selected");

//      init_decoding(peer, videoWidth, videoHeight);

      if (!open_codec(peer, inputFormat.getEncoding()))
          throw new ResourceUnavailableException("Couldn't open codec for " + inputFormat.toString());
    }

    public void close() {
      System.out.println("AVCODEC: close");
      close_codec( peer );
    }

    public void reset() {
      System.out.println("AVCODEC: reset");
      try {
          close();
          open();
      }
      catch(Exception e) {
          e.printStackTrace();
      }

    }

    public void finalize() {
        close();
    }


   public int process(Buffer inputBuffer, Buffer outputBuffer) {

      if (!checkInputBuffer(inputBuffer) ) {
         return BUFFER_PROCESSED_FAILED;
      }

      if (isEOM(inputBuffer) ) {
         propagateEOM(outputBuffer);
         return BUFFER_PROCESSED_OK;
      }

      int outMaxLength=131072;//outputFormat.getMaxDataLength();
      Object outDataTmp = getOutputData(outputBuffer);


      if ( outDataTmp == null || outputBuffer.getFormat() != outputFormat ||
           !outputBuffer.getFormat().equals(outputFormat) ) {
        outputBuffer.setLength(outMaxLength);
        outputBuffer.setFormat(outputFormat);
      }

      outDataTmp = validateData(outputBuffer, 0, true);
      boolean ret = decodeData(inputBuffer,outputBuffer);

      if (ret) {
           updateOutput(outputBuffer,outputFormat, outMaxLength, 0);
           return BUFFER_PROCESSED_OK;
       }
       else {
         if (DEBUG)
           System.out.println("[JavaDecoder] : returning OUTPUT_BUFFER_NOT_FILLED; ");
         return OUTPUT_BUFFER_NOT_FILLED;
       }


    }



    boolean decodeData(Buffer inputBuffer,Buffer outputBuffer) {

        int outMaxLength=131072;//outputFormat.getMaxDataLength();
        int inputLength = inputBuffer.getLength();
        //byte [] outData = (byte [])validateByteArraySize(outputBuffer,outMaxLength );//outputBuffer.getData();
        int [] outData = (int [])validateIntArraySize(outputBuffer,outMaxLength );
        long outDataBytes = getNativeData(outData);
        byte[] inputData = (byte [])inputBuffer.getData();
        long inDataBytes = getNativeData(inputData);


        if (inputLength <= 0) {
            return false;
        }

        boolean res = convert(peer, inputData, inDataBytes, inputBuffer.getOffset(), outData, outDataBytes, inputLength, inputBuffer.getTimeStamp()/1000000000.0);
        int size = lastAudioSize(peer);
        outputBuffer.setLength(size);
        return res;
    }

    public boolean checkFormat(Format format) {

        return super.checkFormat(format);
    }


}