error in framerate output- changing code of dyble

i've used and changed code write by andy dyble(jmfcam05s.java), for read stream not from a cam but from a file plain avi, i've put in input a file with different framerate such as 5-10 or more until 100, but the output is always the same for fixed format(like 640*480 pixels)

p.start();

ds=p.getDataOutput();

try

{

PushBufferDataSource bufferSource =(PushBufferDataSource)ds;

pbs = bufferSource.getStreams()[0];

//this plot the framerate of the sourge

//System.out.println("Format Output buffer"+pbs.getFormat());

RGBFormat streamFormat = (RGBFormat)pbs.getFormat();

BufferToImage converter = new BufferToImage(streamFormat);

}

catch(Exception e){System.out.println("err:"+e);}

try{ds.start();

}catch(Exception e){System.out.println("Exception dataSource.start() "+e);}

// Some gui setup

setLayout(new FlowLayout());

setTitle("Webcam Tesi");

//Dimensione dello schermo

imgPanel currPanel = new imgPanel(new Dimension(imy,imx));

add(currPanel);

pack();Thread.yield();pack();

setLocation(10,20);

setVisible(true);

Image resultImage = this.createImage(imx,imy);

Graphics resultGraphics = resultImage.getGraphics();

resultGraphics.setFont(new Font("Arial", 0, 12));

resultGraphics.setColor(Color.red);

int[] inpix=new int[imx * imy];

int[] outpix=new int[imx * imy];

b=new Buffer();

DirectColorModel dcm = new DirectColorModel(24, 0x00FF0000, 0x0000FF00, 0x000000FF);

MemoryImageSource sourceImage = new MemoryImageSource(imx, imy, dcm, outpix, 0, imx);

Image outputImage;

active=true;

boolean frameOK;

while(active==true)

{

//--

calculating the output framerate it's different by the input.

can help me? please

[1863 byte] By [federico81a] at [2007-11-27 6:46:18]
# 1

the complete code:

/*

* tester.java

*

* Copyright (c) 2006 Andy Dyble. All Rights Reserved.

*

* Permission is hereby granted, free of charge, to any person obtaining a copy of this software

* and associated documentation files (the "Software"), to deal in the Software without

* restriction, including without limitation the rights to use, copy, modify, merge, publish,

* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the

* Software is furnished to do so, subject to the following conditions:

*

* The above copyright notice and this permission notice shall be included in all copies or

* substantial portions of the Software.

*

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING

* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND

* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN

* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

*

* Except as contained in this notice, the name of the author shall not be used in

* advertising or otherwise to promote the sale, use or other dealings in this Software without

* prior written authorization from the author.

*

*/

/*

* Java Media Framework

*

* Copyright (c) 1999-2001 Sun Microsystems, Inc. All Rights Reserved.

*

* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,

* modify and redistribute this software in source and binary code form,

* provided that i) this copyright notice and license appear on all copies of

* the software; and ii) Licensee does not utilize the software in a manner

* which is disparaging to Sun.

*

* This software is provided "AS IS," without a warranty of any kind. ALL

* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY

* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR

* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE

* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING

* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS

* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,

* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER

* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF

* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE

* POSSIBILITY OF SUCH DAMAGES.

*

* This software is not designed or intended for use in on-line control of

* aircraft, air traffic, aircraft navigation or aircraft communications; or in

* the design, construction, operation or maintenance of any nuclear

* facility. Licensee represents and warrants that it will not use or

* redistribute the Software for such purposes.

*/import java.awt.*;

import java.lang.System;

import java.util.*;

import java.io.*;

import javax.media.*;

import javax.media.util.*;

import javax.media.protocol.*;

import javax.media.control.*;

import javax.media.format.*;

import java.awt.image.*;

import java.net.*;

import javax.media.Format;

public class tester extends Frame implements ControllerListener{

Processor p;

PushBufferStream pbs;

Buffer b;

static int cont=1;

static int contacq=1;

byte[] inData;

static int imx=320;

static int imy=240;

static long[] tempiacq=new long[10000];

static long[] tempiin=new long[10000];

static long[] tempiout=new long[10000];

static long[] tempielab=new long[10000];

static long[] tempipres=new long[10000];

static long[] framerate=new long[10000];

DataSource ds;

static int alfa=1;

static int contatore=0;

static int maxis=300;

Boolean active;

boolean stateTransitionOK = true;

Object waitSync = new Object();

public static void main(String...args) throws Throwable {

new tester().startApp();

}

public void startApp(){

//localizzo il file

MediaLocator ml=new MediaLocator("file:/C:/Output.avi");

try {

p = Manager.createProcessor(ml);

} catch (Exception e) {

System.err.println("Impossibile creare il processore dall'url specificato: " + e);

}

p.addControllerListener(this);

// Mettiamo il Processor nello stato configurato in modo da poter

// settare le opzioni del Processor

p.configure();

if (!waitForState(p.Configured)) {

System.err.println("Configurazione del Processor fallita.");

}

// Poniamo l'uscita del Processor di tipo RAW.

//p.setContentDescriptor(new ContentDescriptor(FileTypeDescriptor.RAW));

// Settiamo il formato della traccia

TrackControl tcs[] = p.getTrackControls();

Format f[] = tcs[0].getSupportedFormats();

/* for(int i=0;i<f.length;i++){

System.out.println("f+"+f);

}*/

// int FPS=30;

// VideoFormat sp=new VideoFormat(VideoFormat.RGB,null,-1,null,(float)FPS);

if (f == null || f.length ><= 0) {

System.err.println("Questo formato non ?supportato: "+ tcs[0].getFormat());

}

//tcs[0].setFormat(sp.intersects(f[0]));

tcs[0].setFormat(f[0]);

System.err.println("Il formato settato della traccia ? " + f[0]);

// Realizziamo il Processor

p.realize();

if (!waitForState(p.Realized)) {

System.err.println("Realizzazione del Processor fallita.");

}

;

//avvio del processore

p.start();

ds=p.getDataOutput();

try

{

PushBufferDataSource bufferSource =(PushBufferDataSource)ds;

pbs = bufferSource.getStreams()[0];

//System.out.println("Formato Uscita buffer"+pbs.getFormat());

RGBFormat streamFormat = (RGBFormat)pbs.getFormat();

BufferToImage converter = new BufferToImage(streamFormat);

}

catch(Exception e){System.out.println("err:"+e);}

try{ds.start();

}catch(Exception e){System.out.println("Exception dataSource.start() "+e);}

// Some gui setup

setLayout(new FlowLayout());

setTitle("Webcam Tesi");

//Dimensione dello schermo

imgPanel currPanel = new imgPanel(new Dimension(imy,imx));

add(currPanel);

pack();Thread.yield();pack();

setLocation(10,20);

setVisible(true);

Image resultImage = this.createImage(imx,imy);

Graphics resultGraphics = resultImage.getGraphics();

resultGraphics.setFont(new Font("Arial", 0, 12));

resultGraphics.setColor(Color.red);

int[] inpix=new int[imx * imy];

int[] outpix=new int[imx * imy];

b=new Buffer();

DirectColorModel dcm = new DirectColorModel(24, 0x00FF0000, 0x0000FF00, 0x000000FF);

MemoryImageSource sourceImage = new MemoryImageSource(imx, imy, dcm, outpix, 0, imx);

Image outputImage;

active=true;

boolean frameOK;

while(active==true)

{

//A - fase di acquisizione

settempo(0,tempocorrente());

frameOK = camFetchFrame();

if(frameOK==false)// inData is null

{

try{Thread.sleep(5);}catch(Exception e){}

continue;

}else{

//B estremo inferiore fase di elaborazione

settempo(1,tempocorrente());

}

createPixels(inpix);

process(inpix,outpix);

// outputImage=bti.createImage(b);

outputImage = createImage(sourceImage);

resultGraphics.drawImage(outputImage,0,0,this);

//B' estremo superiore fase di elaborazione

settempo(2,tempocorrente());

//resultGraphics.drawString("tempo uscita:sono qui"+cont+" "+tempocorrente(),20,20);

cont++;

currPanel.setImage(resultImage);

try{Thread.sleep(5);}catch(Exception e){}

Thread.yield();

//C - fase di presentazione

settempo(3,tempocorrente());

if(cont==maxis){

for(int j=1;j<(maxis-1);j++){

System.out.println("a "+tempielab[j]);

System.out.println("b "+tempipres[j]);

System.out.println("c "+tempiacq[j]);

System.out.println("d "+framerate[j]);

}

}

}

}

/**

* Creates array of rgb pixel values for cam

*

*/

void createPixels(int[] prepix)// may need to amend this for other OS ColorModels

{

boolean flip=true;

{

int srcPtr = 0;

int dstPtr = 0;

int dstInc = 0;

if(flip)

{

dstPtr = imx* (imy - 1);

dstInc = -2 * imx;

}

for(int y = 0; y < imy; y++)

{

for(int x = 0; x < imx; x++)

{

byte red = inData[srcPtr + 2];

byte green = inData[srcPtr + 1];

byte blue = inData[srcPtr];

int pixel = (red & 0xff) << 16 | (green & 0xff) << 8 | (blue & 0xff) << 0;

prepix[dstPtr] = pixel;

srcPtr += 3;

dstPtr += 1;

}

dstPtr += dstInc;

}

}

Thread.yield();

}

void processExit()

{

active = false;

try

{

ds.stop();

ds.disconnect();

}

catch(Exception e){}

dispose();

}

/**

* Processes the frame data

*

*/

void process(int[] prepix, int[] postpix)

{

// R = (pixels[index] >> 16) & 0xff;

// G = (pixels[index] >> 8) & 0xff;

// B = (pixels[index]) & 0xff;

// pixels[index] = (R & 0xff) << 16 | (G & 0xff) << 8 | (B & 0xff) << 0;

// this just copies in to out

System.arraycopy(prepix, 0, postpix, 0, prepix.length);

}

/**

* Gets an image via datasource

*

*/

boolean camFetchFrame()

{

try

{

pbs.read(b);

inData=(byte[])b.getData();

if(b.isDiscard()){inData=null;

}

Thread.yield();

}

catch(Exception e){}

if(inData==null) {return false;

}else{

return true;}

}

//metodi del processore importati

public void addNotify() {

super.addNotify();

pack();

}

boolean waitForState(int state) {

synchronized (waitSync) {

try {

while (p.getState() != state && stateTransitionOK)

waitSync.wait();

} catch (Exception e) {}

}

return stateTransitionOK;

}

/**

* Controller Listener.

*/

public void controllerUpdate(ControllerEvent evt) {

if (evt instanceof ConfigureCompleteEvent ||

evt instanceof RealizeCompleteEvent ||

evt instanceof PrefetchCompleteEvent) {

synchronized (waitSync) {

stateTransitionOK = true;

waitSync.notifyAll();

}

} else if (evt instanceof ResourceUnavailableEvent) {

synchronized (waitSync) {

stateTransitionOK = false;

waitSync.notifyAll();

}

} else if (evt instanceof EndOfMediaEvent) {

p.close();

System.exit(0);

}

}

class imgPanel extends Panel

{

Dimension size;

public Image myimg = null;

public imgPanel(Dimension size)

{

super();

this.size = size;

}

public Dimension getPreferredSize()

{

return size;

}

public void update(Graphics g)

{

paint(g);

}

public void paint(Graphics g)

{

if (myimg != null)

{

g.drawImage(myimg, 0, 0, this);

}

}

public void setImage(Image img)

{

if(img!=null)

{

this.myimg = img;

update(getGraphics());

}

}

}

/**

* calcolo tempi e salvataggio valori

*

*/

public void salvatmp(int pos)

{//numero campioni

if(pos<maxis){

tempiacq[pos]=tempiin[pos]-tempiacq[pos];

tempielab[pos]=tempiout[pos]-tempiin[pos];

tempipres[pos]=framerate[pos]-tempiout[pos];

}

}

/**

* Tempo attuale

*

*/

public long tempocorrente()

{long tmp;

tmp=System.nanoTime();

return tmp;

}

/*

* fissa i tempi

*

*/

public void settempo(int app,long tim)

{

//tempi ingresso

if(alfa><maxis){

if(app==0){tempiacq[alfa]=tim;

}

if(app==1){tempiin[alfa]=tim;

}

if(app==2){tempiout[alfa]=tim;

}

if(app==3){

framerate[alfa]=tim;

salvatmp(alfa);

alfa++;

}

if(alfa==maxis){

System.out.println("Frame elaborati totali:"+alfa);

}

}}

}>

federico81a at 2007-7-12 18:18:47 > top of Java-index,Security,Cryptography...
# 2
why setting the framerate of processor, the buffering has another framerate of acquisition?thx, please help me.
federico81a at 2007-7-12 18:18:48 > top of Java-index,Security,Cryptography...
# 3

I am not entirely sure what you are trying to achieve, but do feel that using jmfcam05s.java for other than a webcam would prove difficult.

I suggest that you actually take a look at FrameAccess.java from http://java.sun.com/products/java-media/jmf/2.1.1/solutions/FrameAccess.html and make some simple changes to see if it helps. I suggest that you try :-

(i) in the PostAccessCodec method accessFrame at the end of the source, and at the end of that method, include the following or similar and watch what plays.

if(frame.getSequenceNumber()==0)System.out.println(p.getRate());

if(frame.getSequenceNumber()==10)System.out.println(p.setRate(5.0F));

if(frame.getSequenceNumber()==50)System.out.println(p.setRate(1.0F));

(ii) alternatively, at the end of the process method before the return statement include

int fps=1;out.setTimeStamp(in.getSequenceNumber()*1000000000/fps);

What these do may well be useful for what you are looking to do.

andyblea at 2007-7-12 18:18:48 > top of Java-index,Security,Cryptography...
# 4

my objective is to acquire from webcam and file (because mine webcam has physical limits in the framerate ones), and to estimate the times of elaboration (let alone the times of presentation and acquisition) for every frame, to the aim to understand when the saturation for framerate determining in income is caught up. in frameaccess, I succeed to obtain only a portion of the time total that is that one of codifies.

in your code I have modified source, the strange thing is that pure having set up framerate to the processor, the buffering happens in advanced times to the source.

thanks sincerely for helping.

federico

federico81a at 2007-7-12 18:18:48 > top of Java-index,Security,Cryptography...
# 5

You would probably find that frame acquisition is in several stages, firstly the native operating system gathers frames from the webcam at a requested framerate, eg default 15, max 30, and this is put into a circular buffer in the jmf sourcestream. These are parsed to then feed any preprocessing, and this can get many frames ahead of the presentation. These frames then get processed with any later codecs, and can then be played in sync to time for their timestamps, or any output format framerate if that is possible to change directly or by the clock rate.

andyblea at 2007-7-12 18:18:48 > top of Java-index,Security,Cryptography...