From 0b4696a6df5df4b1325e2a8cdd54447cd994bf02 Mon Sep 17 00:00:00 2001 From: sblantipodi Date: Wed, 15 Nov 2023 22:38:21 +0100 Subject: [PATCH] NVIDIA CUDA Linux pipeline --- .../java/org/dpsoftware/FireflyLuciferin.java | 2 ++ .../org/dpsoftware/config/Configuration.java | 27 +++++++++++----- .../java/org/dpsoftware/config/Constants.java | 4 ++- .../gui/controllers/MiscTabController.java | 6 ++-- .../gui/controllers/ModeTabController.java | 31 ++++++++++++++++--- .../gui/controllers/SettingsController.java | 8 ++++- .../dpsoftware/managers/PipelineManager.java | 23 +++++++++----- 7 files changed, 78 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/dpsoftware/FireflyLuciferin.java b/src/main/java/org/dpsoftware/FireflyLuciferin.java index f6cebe5a..54b8bb6e 100644 --- a/src/main/java/org/dpsoftware/FireflyLuciferin.java +++ b/src/main/java/org/dpsoftware/FireflyLuciferin.java @@ -284,7 +284,9 @@ private void launchGrabberAndConsumers() throws AWTException { // Desktop Duplication API producers if ((MainSingleton.getInstance().config.getCaptureMethod().equals(Configuration.CaptureMethod.DDUPL.name())) || (MainSingleton.getInstance().config.getCaptureMethod().equals(Configuration.CaptureMethod.XIMAGESRC.name())) + || (MainSingleton.getInstance().config.getCaptureMethod().equals(Configuration.CaptureMethod.XIMAGESRC_NVIDIA.name())) || (MainSingleton.getInstance().config.getCaptureMethod().equals(Configuration.CaptureMethod.PIPEWIREXDG.name())) + || (MainSingleton.getInstance().config.getCaptureMethod().equals(Configuration.CaptureMethod.PIPEWIREXDG_NVIDIA.name())) || (MainSingleton.getInstance().config.getCaptureMethod().equals(Configuration.CaptureMethod.AVFVIDEOSRC.name()))) { grabberManager.launchAdvancedGrabber(imageProcessor); } else { // Standard Producers diff --git a/src/main/java/org/dpsoftware/config/Configuration.java b/src/main/java/org/dpsoftware/config/Configuration.java index 55680a70..0895f783 100644 --- a/src/main/java/org/dpsoftware/config/Configuration.java +++ b/src/main/java/org/dpsoftware/config/Configuration.java @@ -182,15 +182,26 @@ public LinkedHashMap getLedMatrixInUse(String ledMatrixI return ledMatrix.get(ledMatrixInUse); } - // WinAPI and DDUPL enables GPU Hardware Acceleration, CPU uses CPU brute force only, - // DDUPL (Desktop Duplication API) is recommended in Win8/Win10/Win11 + /** + * WinAPI and DDUPL enables GPU Hardware Acceleration on Windows, CPU uses CPU brute force only. + * DDUPL (Desktop Duplication API) is recommended in Win8/Win10/Win11 and it uses DX11 + * CUDA is used in Linux only, it needs additional libs and it works on Nvidia GPUs only. + */ + @Getter public enum CaptureMethod { - CPU, - WinAPI, - DDUPL, - XIMAGESRC, - PIPEWIREXDG, - AVFVIDEOSRC + CPU("CPU"), + WinAPI("WinAPI"), + DDUPL("DDUPL"), + XIMAGESRC("XIMAGESRC"), + XIMAGESRC_NVIDIA("XIMAGESRC (NVIDIA)"), + PIPEWIREXDG("PIPEWIREXDG"), + PIPEWIREXDG_NVIDIA("PIPEWIREXDG (NVIDIA)"), + AVFVIDEOSRC("AVFVIDEOSRC"); + private final String captureMethod; + + CaptureMethod(String captureMethod) { + this.captureMethod = captureMethod; + } } } \ No newline at end of file diff --git a/src/main/java/org/dpsoftware/config/Constants.java b/src/main/java/org/dpsoftware/config/Constants.java index 94fd0d8d..76430547 100644 --- a/src/main/java/org/dpsoftware/config/Constants.java +++ b/src/main/java/org/dpsoftware/config/Constants.java @@ -492,8 +492,10 @@ public class Constants { // ./gst-launch-1.0 ximagesrc startx=0 endx=3839 starty=0 endy=2159 use-damage=0 ! videoscale ! videoconvert ! autovideosink public static final String GSTREAMER_PIPELINE_WINDOWS_HARDWARE_HANDLE_SM = "d3d11screencapturesrc monitor-handle={0} ! d3d11convert ! d3d11download"; public static final String GSTREAMER_PIPELINE_WINDOWS_HARDWARE_HANDLE = "d3d11screencapturesrc monitor-handle={0} ! d3d11convert"; - public static final String GSTREAMER_PIPELINE_LINUX = "ximagesrc startx={0} endx={1} starty={2} endy={3} use-damage=0 ! videoscale ! videoconvert"; + public static final String GSTREAMER_PIPELINE_XIMAGESRC = "ximagesrc startx={0} endx={1} starty={2} endy={3} use-damage=0 ! videoscale ! videoconvert"; + public static final String GSTREAMER_PIPELINE_XIMAGESRC_CUDA = "ximagesrc startx={0} endx={1} starty={2} endy={3} use-damage=0 ! cudaupload ! cudascale ! cudaconvert ! cudadownload"; public static final String GSTREAMER_PIPELINE_PIPEWIREXDG = "pipewiresrc fd={1} path={2} ! videorate ! videoscale ! videoconvert"; + public static final String GSTREAMER_PIPELINE_PIPEWIREXDG_CUDA = "pipewiresrc fd={1} path={2} ! videorate ! cudaupload ! cudascale ! cudaconvert ! cudadownload"; public static final String GSTREAMER_PIPELINE_MAC = "avfvideosrc capture-screen=true ! videoscale ! videoconvert"; public static final String FRAMERATE_PLACEHOLDER = "framerate=FRAMERATE_PLACEHOLDER/1,"; public static final String FPS_PLACEHOLDER = "FRAMERATE_PLACEHOLDER"; diff --git a/src/main/java/org/dpsoftware/gui/controllers/MiscTabController.java b/src/main/java/org/dpsoftware/gui/controllers/MiscTabController.java index a4c07a45..5ab5177c 100644 --- a/src/main/java/org/dpsoftware/gui/controllers/MiscTabController.java +++ b/src/main/java/org/dpsoftware/gui/controllers/MiscTabController.java @@ -301,8 +301,10 @@ public void initValuesFromSettingsFile(Configuration currentConfig, boolean upda } frameInsertion.setDisable((!currentConfig.getCaptureMethod().equals(Configuration.CaptureMethod.DDUPL.name())) && (!currentConfig.getCaptureMethod().equals(Configuration.CaptureMethod.XIMAGESRC.name())) - && (!currentConfig.getCaptureMethod().equals(Configuration.CaptureMethod.PIPEWIREXDG.name()) - && (!currentConfig.getCaptureMethod().equals(Configuration.CaptureMethod.AVFVIDEOSRC.name())))); + && (!currentConfig.getCaptureMethod().equals(Configuration.CaptureMethod.XIMAGESRC_NVIDIA.name())) + && (!currentConfig.getCaptureMethod().equals(Configuration.CaptureMethod.PIPEWIREXDG.name())) + && (!currentConfig.getCaptureMethod().equals(Configuration.CaptureMethod.PIPEWIREXDG_NVIDIA.name())) + && (!currentConfig.getCaptureMethod().equals(Configuration.CaptureMethod.AVFVIDEOSRC.name()))); gamma.setValue(String.valueOf(MainSingleton.getInstance().config.getGamma())); colorMode.setValue(Enums.ColorMode.values()[MainSingleton.getInstance().config.getColorMode() - 1].getI18n()); if (!MainSingleton.getInstance().config.getDesiredFramerate().equals(Enums.Framerate.UNLOCKED.getBaseI18n())) { diff --git a/src/main/java/org/dpsoftware/gui/controllers/ModeTabController.java b/src/main/java/org/dpsoftware/gui/controllers/ModeTabController.java index ee5fa6fe..52b51684 100644 --- a/src/main/java/org/dpsoftware/gui/controllers/ModeTabController.java +++ b/src/main/java/org/dpsoftware/gui/controllers/ModeTabController.java @@ -27,6 +27,7 @@ import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.input.InputEvent; +import javafx.util.StringConverter; import org.dpsoftware.MainSingleton; import org.dpsoftware.NativeExecutor; import org.dpsoftware.config.Configuration; @@ -93,9 +94,6 @@ public void injectSettingsController(SettingsController settingsController) { */ @FXML protected void initialize() { - if (NativeExecutor.isLinux()) { - captureMethod.getItems().addAll(Configuration.CaptureMethod.XIMAGESRC, Configuration.CaptureMethod.PIPEWIREXDG); - } for (Enums.Algo al : Enums.Algo.values()) { algo.getItems().add(al.getI18n()); } @@ -111,6 +109,31 @@ protected void initialize() { } } + /** + * Handle key valye combo box + */ + public void setCaptureMethodConverter() { + captureMethod.setConverter(new StringConverter<>() { + @Override + public String toString(Configuration.CaptureMethod object) { + return switch (object) { + case CPU -> Configuration.CaptureMethod.CPU.name(); + case WinAPI -> Configuration.CaptureMethod.WinAPI.name(); + case DDUPL -> Configuration.CaptureMethod.DDUPL.name(); + case XIMAGESRC -> Configuration.CaptureMethod.XIMAGESRC.name(); + case XIMAGESRC_NVIDIA -> Configuration.CaptureMethod.XIMAGESRC_NVIDIA.getCaptureMethod(); + case PIPEWIREXDG -> Configuration.CaptureMethod.PIPEWIREXDG.name(); + case PIPEWIREXDG_NVIDIA -> Configuration.CaptureMethod.PIPEWIREXDG_NVIDIA.getCaptureMethod(); + default -> null; + }; + } + @Override + public Configuration.CaptureMethod fromString(String string) { + return null; + } + }); + } + /** * Init combo boxes */ @@ -156,7 +179,7 @@ void initDefaultValues() { if (NativeExecutor.isWindows()) { captureMethod.setValue(Configuration.CaptureMethod.DDUPL); } else if (NativeExecutor.isMac()) { - captureMethod.setValue(Configuration.CaptureMethod.DDUPL); + captureMethod.setValue(Configuration.CaptureMethod.AVFVIDEOSRC); } else { if (System.getenv(Constants.DISPLAY_MANAGER_CHK).equalsIgnoreCase(Constants.WAYLAND)) { captureMethod.setValue(Configuration.CaptureMethod.PIPEWIREXDG); diff --git a/src/main/java/org/dpsoftware/gui/controllers/SettingsController.java b/src/main/java/org/dpsoftware/gui/controllers/SettingsController.java index 816f470c..73897cbb 100644 --- a/src/main/java/org/dpsoftware/gui/controllers/SettingsController.java +++ b/src/main/java/org/dpsoftware/gui/controllers/SettingsController.java @@ -526,8 +526,12 @@ void setCaptureMethod(Configuration config) { } else { if (modeTabController.captureMethod.getValue() == Configuration.CaptureMethod.XIMAGESRC) { config.setCaptureMethod(Configuration.CaptureMethod.XIMAGESRC.name()); + } else if (modeTabController.captureMethod.getValue() == Configuration.CaptureMethod.XIMAGESRC_NVIDIA) { + config.setCaptureMethod(Configuration.CaptureMethod.XIMAGESRC_NVIDIA.name()); } else if (modeTabController.captureMethod.getValue() == Configuration.CaptureMethod.PIPEWIREXDG) { config.setCaptureMethod(Configuration.CaptureMethod.PIPEWIREXDG.name()); + } else if (modeTabController.captureMethod.getValue() == Configuration.CaptureMethod.PIPEWIREXDG_NVIDIA) { + config.setCaptureMethod(Configuration.CaptureMethod.PIPEWIREXDG_NVIDIA.name()); } } } @@ -756,9 +760,11 @@ public void initOutputDeviceChooser(boolean initCaptureMethod) { } else if (NativeExecutor.isMac()) { modeTabController.captureMethod.getItems().addAll(Configuration.CaptureMethod.AVFVIDEOSRC); } else { - modeTabController.captureMethod.getItems().addAll(Configuration.CaptureMethod.XIMAGESRC, Configuration.CaptureMethod.PIPEWIREXDG); + modeTabController.captureMethod.getItems().addAll(Configuration.CaptureMethod.XIMAGESRC, Configuration.CaptureMethod.XIMAGESRC_NVIDIA, + Configuration.CaptureMethod.PIPEWIREXDG, Configuration.CaptureMethod.PIPEWIREXDG_NVIDIA); } } + modeTabController.setCaptureMethodConverter(); if (NativeExecutor.isWindows()) { SerialManager serialManager = new SerialManager(); Map availableDevices = serialManager.getAvailableDevices(); diff --git a/src/main/java/org/dpsoftware/managers/PipelineManager.java b/src/main/java/org/dpsoftware/managers/PipelineManager.java index 45ceef45..fdcf66d8 100644 --- a/src/main/java/org/dpsoftware/managers/PipelineManager.java +++ b/src/main/java/org/dpsoftware/managers/PipelineManager.java @@ -82,6 +82,7 @@ record XdgStreamDetails(Integer streamId, FileDescriptor fileDescriptor) {} * FileDescriptor from org.freedesktop.portal.ScreenCast:OpenPipeWireRemote */ @SneakyThrows + @SuppressWarnings("all") public static XdgStreamDetails getXdgStreamDetails() { CompletableFuture sessionHandleMaybe = new CompletableFuture<>(); CompletableFuture streamIdMaybe = new CompletableFuture<>(); @@ -136,26 +137,34 @@ public static XdgStreamDetails getXdgStreamDetails() { */ public static String getLinuxPipelineParams() { String gstreamerPipeline; - - if (MainSingleton.getInstance().config.getCaptureMethod().equals(Configuration.CaptureMethod.PIPEWIREXDG.name())) { + String pipeline; + if (MainSingleton.getInstance().config.getCaptureMethod().equals(Configuration.CaptureMethod.PIPEWIREXDG.name()) + || MainSingleton.getInstance().config.getCaptureMethod().equals(Configuration.CaptureMethod.PIPEWIREXDG_NVIDIA.name())) { + if (MainSingleton.getInstance().config.getCaptureMethod().equals(Configuration.CaptureMethod.PIPEWIREXDG.name())) { + pipeline = Constants.GSTREAMER_PIPELINE_PIPEWIREXDG; + } else { + pipeline = Constants.GSTREAMER_PIPELINE_PIPEWIREXDG_CUDA; + } XdgStreamDetails xdgStreamDetails = getXdgStreamDetails(); - - gstreamerPipeline = Constants.GSTREAMER_PIPELINE_PIPEWIREXDG + gstreamerPipeline = pipeline .replace("{1}", String.valueOf(xdgStreamDetails.fileDescriptor.getIntFileDescriptor())) .replace("{2}", xdgStreamDetails.streamId.toString()); } else { // startx{0}, endx{1}, starty{2}, endy{3} + if (MainSingleton.getInstance().config.getCaptureMethod().equals(Configuration.CaptureMethod.XIMAGESRC.name())) { + pipeline = Constants.GSTREAMER_PIPELINE_XIMAGESRC; + } else { + pipeline = Constants.GSTREAMER_PIPELINE_XIMAGESRC_CUDA; + } DisplayManager displayManager = new DisplayManager(); List displayList = displayManager.getDisplayList(); DisplayInfo monitorInfo = displayList.get(MainSingleton.getInstance().config.getMonitorNumber()); - - gstreamerPipeline = Constants.GSTREAMER_PIPELINE_LINUX + gstreamerPipeline = pipeline .replace("{0}", String.valueOf((int) (monitorInfo.getMinX() + 1))) .replace("{1}", String.valueOf((int) (monitorInfo.getMinX() + monitorInfo.getWidth() - 1))) .replace("{2}", String.valueOf((int) (monitorInfo.getMinY()))) .replace("{3}", String.valueOf((int) (monitorInfo.getMinY() + monitorInfo.getHeight() - 1))); } - log.info(gstreamerPipeline); return gstreamerPipeline; }