java-native-access / jna

Java Native Access
Other
8.38k stars 1.66k forks source link

Please add Windows 10 Desktop Duplication API support #1207

Open sblantipodi opened 4 years ago

sblantipodi commented 4 years ago

Provide complete information about the problem

  1. Version of JNA and related jars = JNA 5.5.0
  2. Version and vendor of the java virtual machine = JDK 11
  3. Operating system = Windows 10
  4. System architecture (CPU type, bitness of the JVM) = i7 5930K 6 cores
  5. Complete description of the problem

Windows 8 introduces Desktop Duplication API, (improved with Windows 10) that allow for fast screen capturing without any lag.

Will you ever support this API? Is there a way to capture a screenshot using JNA and Windows Desktop Duplication API?

sblantipodi commented 4 years ago

just for reference in the issue. Thanks to the "great Daniel" I tried to map that function but I ended to crash on a wall.

This is what I tried...

Created the Dxgi.java class

public interface Dxgi extends Library {
    Dxgi INSTANCE = Native.load("Dxgi", Dxgi.class, W32APIOptions.DEFAULT_OPTIONS);
    public WinNT.HRESULT AcquireNextFrame(int TimeoutInMilliseconds, DXGI_OUTDUPL_FRAME_INFO pFrameInfo, PointerByReference ppDesktopResource);    
}

DXGI_OUTDUPL_FRAME_INFO.java

@Structure.FieldOrder({"LastPresentTime", "LastMouseUpdateTime", "AccumulatedFrames", "RectsCoalesced",
        "ProtectedContentMaskedOut", "PointerPosition", "TotalMetadataBufferSize", "PointerShapeBufferSize"})
@Getter @Setter
public class DXGI_OUTDUPL_FRAME_INFO extends Structure {
    public WinNT.LARGE_INTEGER LastPresentTime;
    public WinNT.LARGE_INTEGER LastMouseUpdateTime;
    public int AccumulatedFrames;
    public boolean RectsCoalesced;
    public boolean ProtectedContentMaskedOut;
    public DXGI_OUTDUPL_POINTER_POSITION PointerPosition;
    public int TotalMetadataBufferSize;
    public int PointerShapeBufferSize;

    public DXGI_OUTDUPL_FRAME_INFO() {
    }

}

DXGI_OUTDUPL_POINTER_POSITION.java

@Structure.FieldOrder({"Position", "Visible"})
@Getter @Setter
public class DXGI_OUTDUPL_POINTER_POSITION extends Structure {

    public Pointer Position;
    public boolean Visible;

    public DXGI_OUTDUPL_POINTER_POSITION() {
    }
}

When I try to use this mapping in my main.java like this

Dxgi dxgi = Dxgi.INSTANCE;
PointerByReference ppDesktopResource = new PointerByReference();
DXGI_OUTDUPL_FRAME_INFO frameInfo = new DXGI_OUTDUPL_FRAME_INFO();
dxgi.AcquireNextFrame(33,frameInfo,ppDesktopResource);

I hit the wall with an exception I'm not able to solve.

Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'AcquireNextFrame': The specified procedure could not be found.

Hope that there is a solution to the problem.

stefan-reich commented 1 year ago

Yes, I would love to see this work too. I'm currently using java.awt.Robot and one screenshot takes 50ms on average on my definitely not "slow" Ryzen PC. So I'm only getting 20fps and have to sacrifice a full core just for making screenshots.

I want full 60 fps just like e.g. OBS is achieving without breaking a sweat. I think this API will do this, but how to correctly access it in JNA?

We do have a hint though @sblantipodi - your exception. Maybe it's just an error in the method signature?

I'll just put my thought process in here and keep editing this comment. Bear in mind I'm a noob to JNA and to the Windows API.

So I guess the method we are looking to call is IDXGIOutputDuplication::AcquireNextFrame.

The double colon seems to indicate (remember, I'm a relative noob in 2 out of 3 techs involved here) that AcquireNextFrame is a method in a class named IDXGIOutputDuplication. However, I don't see the name IDXGIOutputDuplication anywhere in your code. Maybe that's an error?

I should just dive in to JNA and start to build this myself.

sblantipodi commented 1 year ago

in the JNA mailing list, main devs says that they are interested in adding DDUPL API in JNA. I think that it will take time...

stefan-reich commented 1 year ago

@sblantipodi It's this thread, right?

I just read it. So in June 2020 you set out to learning JNI... :) Any progress with that? The Java ecosystem would benefit so greatly from fast screenshots on Windows!