Skip to content

Commit

Permalink
Test fast frame redraw hack
Browse files Browse the repository at this point in the history
  • Loading branch information
berry120 committed Feb 12, 2024
1 parent 27dcacc commit dc0375d
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Quelea/launch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ cd $SNAP/jar
export GST_PLUGIN_PATH=$SNAP/usr/lib/x86_64-linux-gnu/gstreamer-1.0
export GST_PLUGIN_SCANNER=$SNAP/usr/lib/x86_64-linux-gnu/gstreamer-1.0/gst-plugin-scanner
export G_FILENAME_ENCODING=UTF-8
jvm/bin/java --add-exports=javafx.graphics/com.sun.javafx.scene.traversal=ALL-UNNAMED --add-exports=javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED --add-exports=javafx.graphics/com.sun.javafx.css=ALL-UNNAMED --add-exports=javafx.base/com.sun.javafx.runtime=ALL-UNNAMED --add-exports=javafx.base/com.sun.javafx.event=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens javafx.controls/javafx.scene.control=ALL-UNNAMED -Djdk.gtk.verbose=true -DVLCJ_INITX=no -Duser.dir=$SNAP/jar -Dfile.encoding=UTF-8 -Dprism.dirtyopts=false -Djavafx.cachedir=$SNAP_USER_COMMON -jar $SNAP/jar/Quelea.jar --userhome=$SNAP_USER_COMMON
jvm/bin/java --add-opens java.base/java.nio=ALL-UNNAMED --add-exports=javafx.graphics/com.sun.javafx.scene.traversal=ALL-UNNAMED --add-exports=javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED --add-exports=javafx.graphics/com.sun.javafx.css=ALL-UNNAMED --add-exports=javafx.base/com.sun.javafx.runtime=ALL-UNNAMED --add-exports=javafx.base/com.sun.javafx.event=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens javafx.controls/javafx.scene.control=ALL-UNNAMED -Djdk.gtk.verbose=true -DVLCJ_INITX=no -Duser.dir=$SNAP/jar -Dfile.encoding=UTF-8 -Dprism.dirtyopts=false -Djavafx.cachedir=$SNAP_USER_COMMON -jar $SNAP/jar/Quelea.jar --userhome=$SNAP_USER_COMMON
6 changes: 4 additions & 2 deletions Quelea/packr.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"add-exports","javafx.base/com.sun.javafx.runtime=ALL-UNNAMED",
"add-exports","javafx.base/com.sun.javafx.event=ALL-UNNAMED",
"add-opens","java.base/java.lang=ALL-UNNAMED",
"add-opens","javafx.controls/javafx.scene.control=ALL-UNNAMED"
"add-opens","javafx.controls/javafx.scene.control=ALL-UNNAMED",
"add-opens","java.base/java.nio=ALL-UNNAMED"
],
"resources": [
"dist/bibles",
Expand All @@ -35,5 +36,6 @@
"dist/songformat.xsl"
],
"icon": "dist/icons/mac-logo.icns",
"output": "out-mac/Quelea.app"
"output": "out-mac/Quelea.app",
"verbose": true
}
84 changes: 81 additions & 3 deletions Quelea/src/main/java/org/quelea/windows/video/FXImageSink.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
package org.quelea.windows.video;

import com.sun.jna.Pointer;
import javafx.application.Platform;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
Expand All @@ -32,7 +33,11 @@
import org.freedesktop.gstreamer.Structure;
import org.freedesktop.gstreamer.elements.AppSink;

import java.lang.module.ModuleFinder;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;

Expand All @@ -50,16 +55,36 @@ public class FXImageSink {
private final static String DEFAULT_CAPS;
private final static int OLD_SAMPLE_BUFFER_SIZE = 2;

private static final Field mapInfoBufferField;
private static final Field pointerPeerField;
private static final Field bufferAddress;
private static final Field bufferCapacity;

static {
if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
DEFAULT_CAPS = "video/x-raw, format=BGRx";
} else {
DEFAULT_CAPS = "video/x-raw, format=xRGB";
}

try {
mapInfoBufferField = Buffer.class.getDeclaredField("mapInfo");
mapInfoBufferField.setAccessible(true);
pointerPeerField = Pointer.class.getDeclaredField("peer");
pointerPeerField.setAccessible(true);
bufferAddress = java.nio.Buffer.class.getDeclaredField("address");
bufferAddress.setAccessible(true);
bufferCapacity = java.nio.Buffer.class.getDeclaredField("capacity");
bufferCapacity.setAccessible(true);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
}

private final AppSink sink;
private final ReadOnlyObjectWrapper<WritableImage> image;
private IntBuffer imageBuffer;
private PixelBuffer<IntBuffer> pixelBuffer;
private Sample activeSample;
private Buffer activeBuffer;
private final Queue<Sample> oldSamples;
Expand Down Expand Up @@ -94,7 +119,10 @@ public FXImageSink(AppSink sink) {
return FlowReturn.OK;
});
sink.setCaps(Caps.fromString(DEFAULT_CAPS));
image = new ReadOnlyObjectWrapper<>(new WritableImage(1, 1));

imageBuffer = ByteBuffer.allocateDirect(4).asIntBuffer();
pixelBuffer = new PixelBuffer<>(1, 1, imageBuffer, PixelFormat.getIntArgbPreInstance());
image = new ReadOnlyObjectWrapper<>(new WritableImage(pixelBuffer));
}

/**
Expand All @@ -118,7 +146,19 @@ public AppSink getSinkElement() {
return sink;
}

long lastTs = 0;
int frames = 0;

private void updateImage(Sample newSample) {
long ts = System.currentTimeMillis();
if(ts-lastTs>1000) {
System.out.println(frames);
frames = 1;
lastTs= ts;
}
else {
frames++;
}
if (!Platform.isFxApplicationThread()) {
throw new IllegalStateException("Not on FX application thread");
}
Expand All @@ -135,10 +175,45 @@ private void updateImage(Sample newSample) {
activeBuffer = newSample.getBuffer();

if (image.get().getWidth() != width || image.get().getHeight() != height) {
image.set(new WritableImage(width, height));
imageBuffer = ByteBuffer.allocateDirect(width*height*4).asIntBuffer();
pixelBuffer = new PixelBuffer<>(width, height, imageBuffer, PixelFormat.getIntArgbPreInstance());
image.set(new WritableImage(pixelBuffer));
}

image.get().getPixelWriter().setPixels(0, 0, width, height, PixelFormat.getByteBgraPreInstance(), activeBuffer.map(false), width * 4);
IntBuffer gBuffer = activeBuffer.map(false).asIntBuffer();

try {
// GstBufferAPI.MapInfoStruct mapInfo = (GstBufferAPI.MapInfoStruct) mapInfoBufferField.get(activeBuffer);
// long baseAddress = (long)pointerPeerField.get(mapInfo.data);
// long size = mapInfo.size.longValue();

long baseAddress = bufferAddress.getLong(gBuffer);
long size = bufferCapacity.getInt(gBuffer);

// System.out.println(baseAddress + " "+ size);

// imageBuffer.rewind();

bufferAddress.setLong(imageBuffer, baseAddress);
bufferCapacity.setInt(imageBuffer, (int)size);
imageBuffer.position(0);
imageBuffer.limit((int)size);
// System.out.println(imageBuffer.get(4140000));
// System.out.println(gBuffer.get(4140000));
// System.out.println(gBuffer.getClass());
// System.out.println(imageBuffer.getClass());
// imageBuffer.put(gBuffer);

// imageBuffer.flip();

pixelBuffer.updateBuffer(b -> null);


} catch (IllegalAccessException ex) {
ex.printStackTrace();
}

// image.get().getPixelWriter().setPixels(0, 0, width, height, PixelFormat.getByteBgraPreInstance(), activeBuffer.map(false), width * 4);

if (oldSample != null) oldSamples.add(oldSample);
if (oldBuffer != null) {
Expand All @@ -148,6 +223,9 @@ private void updateImage(Sample newSample) {
oldSamples.remove().dispose();
}

// long dur = System.nanoTime() - val;
// System.out.println("REFRESH TIME: " + dur / 1000);

}

/**
Expand Down

0 comments on commit dc0375d

Please sign in to comment.