I have just upgraded to Fobs 0.4, and tried the Java2DRenderer renderer. Previously, I was using Sun's LightWeightRenderer, which gave smooth rendering on repaints, resizes, etc.
I have modified Java2DRenderer to achieve the same affect (by making it extend JPanel instead of creating a private JPanel variable). Below is the source, have fun!
Regards
Keith
===============
public class Java2DRenderer extends JPanel implements VideoRenderer, FrameGrabbingControl {
public Format[] getSupportedInputFormats() {return new Format[] {new RGBFormat() };}
public Format setInputFormat(Format format) {
System.out.println("Fobs Java2DRenderer: setInputFormat");
FobsConfiguration.videoFrameFormat=FobsConfiguration.RGBA;
vf = (RGBFormat) format;
int formatWidth = (int) vf.getSize().getWidth();
int formatHeight = (int) vf.getSize().getHeight();
I have also made more modifications to it. It now works if I have a custom codec with the RGBFormat in byte[], the code expects it to be in int []. The key change is in the bufferToImage() method:
what if the format is a short[]? A cast from short[] to int[] failes.
I can create a DataBufferShort, but the SinglePixelPackedSampleModel only supports unsigned short (or byte). Is there a fast way to convert the int[] to short[] or byte[]?
If I use your suggestion from your last post, I get only a black output.
Regards,
Peter
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi
I have just upgraded to Fobs 0.4, and tried the Java2DRenderer renderer. Previously, I was using Sun's LightWeightRenderer, which gave smooth rendering on repaints, resizes, etc.
I have modified Java2DRenderer to achieve the same affect (by making it extend JPanel instead of creating a private JPanel variable). Below is the source, have fun!
Regards
Keith
===============
public class Java2DRenderer extends JPanel implements VideoRenderer, FrameGrabbingControl {
private BufferStrategy strategy;
public Java2DRenderer() {
}
private RGBFormat vf;
private Image lastImage = null;
void setValue(Object aValue,boolean isSelected) {
System.out.println(aValue.getClass().getName());
}
public Format[] getSupportedInputFormats() {return new Format[] {new RGBFormat() };}
public Format setInputFormat(Format format) {
System.out.println("Fobs Java2DRenderer: setInputFormat");
FobsConfiguration.videoFrameFormat=FobsConfiguration.RGBA;
vf = (RGBFormat) format;
int formatWidth = (int) vf.getSize().getWidth();
int formatHeight = (int) vf.getSize().getHeight();
this.setPreferredSize(new Dimension(formatWidth,formatHeight));
return format;
}
public void start() {
System.out.println("Fobs Java2DRenderer: start");
}
public void stop() {
System.out.println("Fobs Java2DRenderer: stop");
}
public int process(Buffer buffer) {
Graphics2D g2d = (Graphics2D) this.getGraphics();
if(g2d != null) {
if(lastImage == null) lastImage = bufferToImage(buffer);
g2d.drawImage(lastImage, 0, 0, this.getWidth(),this.getHeight(), null);
}
return BUFFER_PROCESSED_OK;
}
protected void paintComponent(Graphics g) {
g.drawImage(lastImage, 0, 0, this.getWidth(),this.getHeight(), null);
}
private BufferedImage bufferToImage(Buffer buffer) {
RGBFormat format = (RGBFormat) buffer.getFormat();
int rMask, gMask, bMask;
Object data = buffer.getData();
DirectColorModel dcm;
rMask = format.getRedMask();
gMask = format.getGreenMask();
bMask = format.getBlueMask();
int [] masks = new int[3];
masks[0] = rMask;
masks[1] = gMask;
masks[2] = bMask;
DataBuffer db = new DataBufferInt((int[])data,
format.getLineStride() *
format.getSize().height);
SampleModel sm = new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT,
format.getLineStride(),
format.getSize().height,
masks);
WritableRaster wr = Raster.createWritableRaster(sm, db, new Point(0, 0));
dcm = new DirectColorModel(24, rMask, gMask, bMask);
return new BufferedImage(dcm, wr, true, null);
}
public String getName() {
return "Fobs Java2DRenderer";
}
public void open() throws ResourceUnavailableException {
}
public void close() {
}
public void reset() {
}
public Component getComponent() {
return this;
}
public boolean setComponent(Component arg0) {
return false;
}
// support for FrameGrabbingControl
public Buffer grabFrame() {
//BufferedImage bufimg = (BufferedImage)FobsConfiguration.properties.get("BufferedImage");
Buffer buf = ImageToBuffer.createBuffer(lastImage,(float)0);
return buf;
}
// No awt component is needed for FrameGrabbingControl
public Component getControlComponent() {
return null;
}
public Object[] getControls() {
Object[] obj = { this };
return obj;
}
public Object getControl(String arg) {
Object rc = null;
if(arg.equals("javax.media.control.FrameGrabbingControl")) rc = this;
return rc;
}
// new code-end
}
==================
Hi,
the new code has been integrated, with minor modifications, and works like a charm!!! I'll commit changes to the CVS in the next few minutes.
Thanks very much for your contribution!!!
Cheers,
Jose San Pedro
Hi Jose
I have also made more modifications to it. It now works if I have a custom codec with the RGBFormat in byte[], the code expects it to be in int []. The key change is in the bufferToImage() method:
private Image bufferToImage(Buffer buffer) {
Object data = buffer.getData();
BufferToImage bufferToImage = new BufferToImage((VideoFormat) buffer.getFormat());
Image image = bufferToImage.createImage(buffer);
return image;
}
Also in the process(Buffer buffer) method, it should always save the lastImage:
public int process(Buffer buffer) {
Graphics2D g2d = (Graphics2D) this.getGraphics();
if(g2d != null) {
g2d.drawImage(lastImage, 0, 0, this.getWidth(),this.getHeight(), null);
}
return BUFFER_PROCESSED_OK;
}
Regards
Keith
Hi Keith, hi Jose,
what if the format is a short[]? A cast from short[] to int[] failes.
I can create a DataBufferShort, but the SinglePixelPackedSampleModel only supports unsigned short (or byte). Is there a fast way to convert the int[] to short[] or byte[]?
If I use your suggestion from your last post, I get only a black output.
Regards,
Peter
Hi Peter
If you see my previous post, I suggested using code that was independent of the type. Works for me, did not matter if it was byte[], short[], etc.
Regards
Keith
Hi Peter
Sorry, I did not read your post properly.
I am not sure why you are getting a black output with the new method suggested.
Regards
Keith
Hi Keith,
I think you missed the line
lastImage = bufferToImage(buffer);
in your post from 2007-01-10 18:36.
It should look like
public int process(Buffer buffer) {
Graphics2D g2d = (Graphics2D) this.getGraphics();
if (g2d != null) {
lastImage = bufferToImage(buffer);
g2d.drawImage(lastImage, 0, 0, this.getWidth(), this.getHeight(), null);
}
return BUFFER_PROCESSED_OK;
}
Did anyone tried this Renderer with RTP-DataSource?
Regards,
Peter
Hi Peter
Ah, not sure how that got missed out, but it has always been in my code.
Sorry about the mistake, however I did mention in the post that we should *always* save the lastImage.
Regards
Keith
Yes thats true, but this doesn't solve the problem with the black output.