Skip to content

Commit

Permalink
NVIDIA CUDA Linux pipeline
Browse files Browse the repository at this point in the history
  • Loading branch information
sblantipodi committed Nov 15, 2023
1 parent 9604170 commit 0b4696a
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 23 deletions.
2 changes: 2 additions & 0 deletions src/main/java/org/dpsoftware/FireflyLuciferin.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 19 additions & 8 deletions src/main/java/org/dpsoftware/config/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -182,15 +182,26 @@ public LinkedHashMap<Integer, LEDCoordinate> 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;
}
}

}
4 changes: 3 additions & 1 deletion src/main/java/org/dpsoftware/config/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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());
}
Expand All @@ -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
*/
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}
}
Expand Down Expand Up @@ -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<String, Boolean> availableDevices = serialManager.getAvailableDevices();
Expand Down
23 changes: 16 additions & 7 deletions src/main/java/org/dpsoftware/managers/PipelineManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> sessionHandleMaybe = new CompletableFuture<>();
CompletableFuture<Integer> streamIdMaybe = new CompletableFuture<>();
Expand Down Expand Up @@ -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<DisplayInfo> 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;
}
Expand Down

0 comments on commit 0b4696a

Please sign in to comment.