Skip to content

Commit

Permalink
fallback to CPU pipeline when needed. AMD GPUs fix.
Browse files Browse the repository at this point in the history
  • Loading branch information
sblantipodi committed Dec 17, 2023
1 parent acef61e commit 113ebfd
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 7 deletions.
1 change: 0 additions & 1 deletion src/main/java/org/dpsoftware/config/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,6 @@ public class Constants {
public static final String INTERNAL_SCALING_Y = "INTERNAL_SCALING_Y";
public static final int RESAMPLING_FACTOR = 4;
public static final String EMIT_SIGNALS = "emit-signals";
public static final int GSTREAMER_MEMORY_DIVIDER = 32;
public static final String GSTREAMER_PIPELINE_DDUPL_SM = "video/x-raw(memory:SystemMemory),width=INTERNAL_SCALING_X,height=INTERNAL_SCALING_Y,sync=false,";
public static final String GSTREAMER_PIPELINE_DDUPL = "video/x-raw(memory:D3D11Memory),width=INTERNAL_SCALING_X,height=INTERNAL_SCALING_Y,sync=false,";
public static final String GSTREAMER_PIPELINE = "video/x-raw,width=INTERNAL_SCALING_X,height=INTERNAL_SCALING_Y,sync=false,";
Expand Down
13 changes: 9 additions & 4 deletions src/main/java/org/dpsoftware/grabber/GStreamerGrabber.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
Expand Down Expand Up @@ -70,9 +71,7 @@ public GStreamerGrabber() {
this(new AppSink("GstVideoComponent"));
ledMatrix = MainSingleton.getInstance().config.getLedMatrixInUse(MainSingleton.getInstance().config.getDefaultLedMatrix());
previousFrame = new Color[ledMatrix.size()];
for (int i = 0; i < previousFrame.length; i++) {
previousFrame[i] = new Color(0, 0, 0);
}
Arrays.fill(previousFrame, new Color(0, 0, 0));
}

/**
Expand All @@ -86,7 +85,7 @@ public GStreamerGrabber(AppSink appsink) {
String gstreamerPipeline;
if (MainSingleton.getInstance().config.getCaptureMethod().equals(Configuration.CaptureMethod.DDUPL.name())) {
// Scale image inside the GPU by RESAMPLING_FACTOR, Constants.GSTREAMER_MEMORY_DIVIDER tells if resolution is compatible with D3D11Memory with no padding.
if ((MainSingleton.getInstance().config.getScreenResX() / Constants.GSTREAMER_MEMORY_DIVIDER) % 2 == 0) {
if (!GrabberSingleton.getInstance().isFallbackPipeline()) {
gstreamerPipeline = Constants.GSTREAMER_PIPELINE_DDUPL
.replace(Constants.INTERNAL_SCALING_X, String.valueOf(MainSingleton.getInstance().config.getScreenResX() / Constants.RESAMPLING_FACTOR))
.replace(Constants.INTERNAL_SCALING_Y, String.valueOf(MainSingleton.getInstance().config.getScreenResY() / Constants.RESAMPLING_FACTOR));
Expand Down Expand Up @@ -180,6 +179,12 @@ public void rgbFrame(int width, int height, IntBuffer rgbBuffer) {
return;
}
int intBufferSize = (width * height) - 1;
if (((rgbBuffer.capacity() - 1) != intBufferSize) && !GrabberSingleton.getInstance().isFallbackPipeline()) {
log.debug("Received buffer is different from the expected, using fallback pipeline.");
GrabberSingleton.getInstance().setFallbackPipeline(true);
PipelineManager.restartCapture(() -> {
}, true);
}
// CHECK_ASPECT_RATIO is true 10 times per second, if true and black bars auto detection is on, auto detect black bars
if (MainSingleton.getInstance().config.isAutoDetectBlackBars()) {
if (GrabberSingleton.getInstance().CHECK_ASPECT_RATIO) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/dpsoftware/grabber/GrabberManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public void launchAdvancedGrabber(ImageProcessor imageProcessor) {
DisplayManager displayManager = new DisplayManager();
String monitorNativePeer = String.valueOf(displayManager.getDisplayInfo(MainSingleton.getInstance().config.getMonitorNumber()).getNativePeer());
// Constants.GSTREAMER_MEMORY_DIVIDER tells if resolution is compatible with D3D11Memory with no padding.
if ((MainSingleton.getInstance().config.getScreenResX() / Constants.GSTREAMER_MEMORY_DIVIDER) % 2 == 0) {
if (!GrabberSingleton.getInstance().isFallbackPipeline()) {
bin = Gst.parseBinFromDescription(Constants.GSTREAMER_PIPELINE_WINDOWS_HARDWARE_HANDLE.replace("{0}", monitorNativePeer), true);
} else {
bin = Gst.parseBinFromDescription(Constants.GSTREAMER_PIPELINE_WINDOWS_HARDWARE_HANDLE_SM.replace("{0}", monitorNativePeer), true);
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/org/dpsoftware/grabber/GrabberSingleton.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ public class GrabberSingleton {
public Rectangle rect;
// GStreamer Rendering pipeline
public Pipeline pipe;
// There is a known issue that prevents to correcly scale the captured image with some resolutions/GPUs.
// for example 3440x1440 on NVIDIA, 1920x1080 on AMD. Scale the image on the CPU if this is the case.
public boolean fallbackPipeline;
float maxPeak, maxRms = 0;
float maxPeakLeft, maxRmsLeft = 0;
float maxPeakRight, maxRmsRight = 0;
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/org/dpsoftware/gui/GuiManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,13 @@ public void stopCapturingThreads(boolean publishToTopic) {
}
}

/**
* Stop capturing threads without sending the signal to the firmware
*/
public void stopPipeline() {
pipelineManager.stopCapturePipeline();
}

/**
* Start capturing threads
*/
Expand Down
16 changes: 15 additions & 1 deletion src/main/java/org/dpsoftware/managers/PipelineManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -469,10 +469,24 @@ public void stopCapturePipeline() {
* @param command callback to execute during the restart process
*/
public static void restartCapture(Runnable command) {
restartCapture(command, false);
}

/**
* Callback used to restart the capture pipeline. It acceps a method as input.
*
* @param command callback to execute during the restart process
* @param pipelineOnly if true, restarts the capturing pipeline but does not send the STOP signal to the firmware
*/
public static void restartCapture(Runnable command, boolean pipelineOnly) {
if (MainSingleton.getInstance().RUNNING) {
Platform.runLater(() -> {
command.run();
MainSingleton.getInstance().guiManager.stopCapturingThreads(MainSingleton.getInstance().RUNNING);
if (pipelineOnly) {
MainSingleton.getInstance().guiManager.stopPipeline();
} else {
MainSingleton.getInstance().guiManager.stopCapturingThreads(MainSingleton.getInstance().RUNNING);
}
CommonUtility.delaySeconds(() -> MainSingleton.getInstance().guiManager.startCapturingThreads(), 4);
});
}
Expand Down

0 comments on commit 113ebfd

Please sign in to comment.