Aktuelle Zeit: 24.09.2018 23:31

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 24 Beiträge ]  Gehe zu Seite 1, 2, 3  Nächste
Autor Nachricht
 Betreff des Beitrags: DXGI Desktop Duplication API (DX11 Win8+) Hilfe gesucht
BeitragVerfasst: 20.06.2018 10:37 
Offline
Benutzeravatar

Registriert: 01.09.2004 22:51
Hat diese API noch nie Jemand hier benutzt? Leider finde ich keinen lauffähigen Beispielcode, nur das hier:

https://www.purebasic.fr/english/viewto ... 13&t=59425

Das ist sicherlich schon sehr hilfreich ist, leider stehe ich da mal wieder wie der Ochs vor dem Berg, ist über dem was ich sonst programmiere. Langsam muss ich einsehen, dass ich nicht mehr der Jüngte bin. :cry: Vielleicht hab ich aber auch nur seit Tagen ein Brett vor dem Kopf. :roll:

Vielleicht hat ja doch Jemand einen Code Schnipsel dazu rum liegen? Oder wenigstens einen hilfreichen Anhaltspunkt für mich?

Werde derweil mal weiter suchen, vielleicht geht mir ja doch noch ein Licht auf.

Edit: Lösung über die Open Source DLL DXGCap.dll: viewtopic.php?p=347617#p347617


Zuletzt geändert von Hoto am 22.06.2018 09:52, insgesamt 2-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: DXGI Desktop Duplication API (DX11 Win8+) Hilfe gesucht
BeitragVerfasst: 21.06.2018 15:36 
Offline
Benutzeravatar

Registriert: 01.09.2004 22:51
Ich poste es auch noch mal hier rein, weil im anderen Thread geht es um das ganze Projekt an sich, hier nur um eben genau jene Funktion.

Ich hab mal etwas rumgesucht und dabei diesen VS C++ DDL/Lib Source gefunden, den ich nun versucht habe zu verwenden:
https://github.com/bryal/DXGCap

Das kompilieren des C++ Codes hat auf Anhieb Fehlerfrei funktioniert.

In PB sieht mein Code nun so aus, der leider nicht richtig funktioniert.

Code:
UsePNGImageEncoder()

Define cs = 0, Width.i, Height.i, buf_size.i, *buf = #Null, o_size.i, *o_bytes

Import "DXGCap.lib"
  create_dxgi_manager()
  delete_dxgi_manager(*dxgi_manager)
  get_capture_source(*dxgi_manager)
  get_frame_bytes(*dxgi_manager, o_size, *o_bytes)
  get_output_dimensions(*dxgi_manager, Width, Height)
  refresh_output(*dxgi_manager)
  set_capture_source(*dxgi_manager,cs)
  set_timeout(*dxgi_manager,timeout)
EndImport

*dxgi_manager = create_dxgi_manager()
Debug *dxgi_manager ; sollte größer 0 sein
get_output_dimensions(*dxgi_manager,@Width,@Height)
Debug "w:"+Str(Width) + " h:" + Str(Height) ; wird korrekt angezeigt
refresh_output(*dxgi_manager)
Debug get_frame_bytes(*dxgi_manager,@buf_size,@*buf) ; sollte größer 0 sein
Debug get_capture_source(*dxgi_manager) ; gibt 0 aus

CreateImage(0,Width,Height,24,RGB(255,255,255))
x = 0 : y = 0 : z = 0
Debug PeekB(*buf) ; sollte nicht 0 sein, außer der erste SubPixel links oben ist tatsächlich 0 (bei Blau)
StartDrawing(ImageOutput(0))
  DrawingMode(#PB_2DDrawing_Default)
  For y = 0 To Height-1
    For x = 0 To Width-1
      Plot(x,y,RGB(PeekB(*buf+z+2),PeekB(*buf+z+1),PeekB(*buf+z))) ; BGRA8 Format
      z + 4
    Next
  Next
StopDrawing()
SaveImage(0,"testdxgi.png",#PB_ImagePlugin_PNG)
delete_dxgi_manager(*dxgi_manager)

Vielleicht sieht ja Jemand direkt wo das Problem liegen könnte. Ich schau mir das später noch mal an.

Nur quick und dirty zum testen.

Das Problem ist nun, dass er zwar die Bildschirm Auflösung korrekt ausließt und auch der Puffer mit den Bilddaten die korrekt Größe zu haben scheint (H * B * 4 inkl. Alpha), aber ich krieg als Farbwerte nur lauter 0er zurück und damit ein komplett schwarzes Bild.

Edit: merkwürdig ist auch, dass wenn ich den Code kompiliere und per Exe ausführe, er am Ende kein Bild erstellt, mit Debugger aber schon.


Zuletzt geändert von Hoto am 04.07.2018 05:46, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: DXGI Desktop Duplication API (DX11 Win8+) Hilfe gesucht
BeitragVerfasst: 21.06.2018 15:50 
Offline
Ein Admin
Benutzeravatar

Registriert: 29.08.2004 20:20
Wohnort: Saarbrücken
Letzteres liegt daran, dass du da solche Zeilen drin hast
Code:
Debug get_frame_bytes(*dxgi_manager,@buf_size,@*buf) ; sollte größer 0 sein

Ohne Debugger bzw. als EXE werden die einfach gar nicht mehr ausgeführt. Mach das Debug davor weg und schon klappt es auch mit der EXE.
Beim Rest kann ich dir nicht gut weiterhelfen mangels Windows. ;-)

Edit:
Ach Moment. Ich sehe den Fehler schon.
get_frame_bytes() erwartet einen vorhandenen Puffer. Es erstellt dir keinen.

Du hast ja einfach nur geschrieben
Code:
*buf = #Null

Du solltest *buf auch mit der richtigen Größe (width * height * 4) initialiseren. Entweder mit AllocateMemory(width * height * 4) oder einfach ein Dim buf.l(width - 1, height - 1) und dann als @buf() übergeben.

_________________
Freakscorner.de - Der Bastelkeller | Neustes Video: Neje DK - 1 Watt Laser Engraver
Ubuntu Gnome 16.04.3 LTS x64, PureBasic 5.60 x64 (außerdem 4.41, 4.50, 4.61, 5.00, 5.10, 5.11, 5.21, 5.22, 5.30, 5.31, 5.40, 5.50)
"Die deutsche Rechtschreibung ist Freeware, du darfst sie kostenlos nutzen – Aber sie ist nicht Open Source, d. h. du darfst sie nicht verändern oder in veränderter Form veröffentlichen."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: DXGI Desktop Duplication API (DX11 Win8+) Hilfe gesucht
BeitragVerfasst: 21.06.2018 16:05 
Offline
Ein Admin
Benutzeravatar

Registriert: 29.08.2004 20:20
Wohnort: Saarbrücken
Hast du diese Lib auch irgendwo für 64-Bit? Ein 32-Bittiges Windows hat doch heute kaum noch jemand.

_________________
Freakscorner.de - Der Bastelkeller | Neustes Video: Neje DK - 1 Watt Laser Engraver
Ubuntu Gnome 16.04.3 LTS x64, PureBasic 5.60 x64 (außerdem 4.41, 4.50, 4.61, 5.00, 5.10, 5.11, 5.21, 5.22, 5.30, 5.31, 5.40, 5.50)
"Die deutsche Rechtschreibung ist Freeware, du darfst sie kostenlos nutzen – Aber sie ist nicht Open Source, d. h. du darfst sie nicht verändern oder in veränderter Form veröffentlichen."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: DXGI Desktop Duplication API (DX11 Win8+) Hilfe gesucht
BeitragVerfasst: 21.06.2018 17:16 
Offline
Benutzeravatar

Registriert: 01.09.2004 22:51
Tja, die Idee war gut, aber weder AllocMemory oder Dim ändern was am Endergebnis, überall steht 0 drin.

Auf das "Debug" am Anfang bin ich eben selbst noch gekommen... dummer Fehler. :lol:

Kann es denn sein das die 32Bit DLL nicht unter Win 64Bit funktioniert? 64Bit hab ich nämlich noch nicht ausprobiert, werd ich gleich mal machen.

Edit: keine Änderung mit 64Bit und das gespeicherte Bild (nach wie vor komplett schwarz). Langsam glaube ich es liegt an der DLL?


Zuletzt geändert von Hoto am 21.06.2018 17:25, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: DXGI Desktop Duplication API (DX11 Win8+) Hilfe gesucht
BeitragVerfasst: 21.06.2018 17:25 
Offline
Ein Admin
Benutzeravatar

Registriert: 29.08.2004 20:20
Wohnort: Saarbrücken
Oder hast du es mal versucht mit ImportC statt Import? Im Github-Code steht ja überall "__declspec", d.h. die Aufrufkonvetion ist cdecl und nicht stdcall. Für cdecl sollte man ImportC nutzen.

Der Code müsste dann glaube ich so aussehen:
Code:
ImportC "DXGCap.lib"
   _create_dxgi_manager()
   _delete_dxgi_manager(*dxgi_manager)
   _get_capture_source(*dxgi_manager)
   _get_frame_bytes(*dxgi_manager, o_size, *o_bytes)
   _get_output_dimensions(*dxgi_manager, Width, Height)
   _refresh_output(*dxgi_manager)
   _set_capture_source(*dxgi_manager,cs)
   _set_timeout(*dxgi_manager,timeout)
EndImport

_________________
Freakscorner.de - Der Bastelkeller | Neustes Video: Neje DK - 1 Watt Laser Engraver
Ubuntu Gnome 16.04.3 LTS x64, PureBasic 5.60 x64 (außerdem 4.41, 4.50, 4.61, 5.00, 5.10, 5.11, 5.21, 5.22, 5.30, 5.31, 5.40, 5.50)
"Die deutsche Rechtschreibung ist Freeware, du darfst sie kostenlos nutzen – Aber sie ist nicht Open Source, d. h. du darfst sie nicht verändern oder in veränderter Form veröffentlichen."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: DXGI Desktop Duplication API (DX11 Win8+) Hilfe gesucht
BeitragVerfasst: 21.06.2018 17:31 
Offline
Benutzeravatar

Registriert: 01.09.2004 22:51
Sicher? Die Funktionen der DLL haben ja eigentlich funktioniert, bis auf das Bild auslesen.

Wenn ich das so ändere wie du angegeben hast, bekomme ich lauter "Unresolved external symbol" POLINK Fehler angezeigt.

64 Bit hatte ich oben schon das dazu editiert, keine Änderung. Eine Idee hab ich noch.

Edit: Hm, interessant. Ich hab jetzt von der Debug Routine im C++ Source übernommen, dass er die get_frame_bytes Funktion 60000x aufruft bevor er die Daten dann wirklich nutzt. Es scheint die Api braucht wohl einen Moment bis sie Daten liefert. Jetzt hab ich zwar ein Bild, aber irgendwas stimmt mit den Farben noch nicht.

Sehe gerade, dass bei den Farbwerten teils auch Minuszahlen dabei sind, woher kann das denn kommen?

Edit2: Ok, mit PeekA statt PeekB geht es, nun passen die Farben und es funktioniert. Werd den Code mal aufräumen und dann noch mal hier posten.

Allerdings muss man die Daten wohl jedes mal prüfen, weil ab und zu kommen immer noch lauter 0er bei raus, aber ich hab da langsam so ein Verdacht... muss ich testen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: DXGI Desktop Duplication API (DX11 Win8+) Hilfe gesucht
BeitragVerfasst: 21.06.2018 18:28 
Offline
Benutzeravatar

Registriert: 30.03.2010 15:24
Code:
Debug get_frame_bytes(*dxgi_manager,@buf_size,@*buf) ; sollte größer 0 sein

Ohm, nee 0 ist CR_OK und somit das gewünschte Ergebnis.

Code:
size_t buf_size;
size_t buf_size;
   uint8_t* buf = NULL;
   for (size_t i = 0; i < 60000; i++) {
      switch (get_frame_bytes(dxgi_manager, &buf_size, &buf)) {
         case CR_OK:
            break;
         case CR_ACCESS_DENIED:
            printf("Access denied\n");
            break;
         case CR_ACCESS_LOST:
            printf("Access lost\n");
            break;
         case CR_TIMEOUT:
            printf("Timeout\n");
            break;
         case CR_FAIL:
            printf("General failure\n");
            break;
      }
   }


get_frame_bytes(dxgi_manager, &buf_size, &buf);


Mit dem Bild stimmt aber trotzdem was nicht.

_________________
PureBasic 5.46 LTS (Windows x86/x64) | windows 10 x64 Falling Bug


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: DXGI Desktop Duplication API (DX11 Win8+) Hilfe gesucht
BeitragVerfasst: 21.06.2018 19:34 
Offline
Benutzeravatar

Registriert: 01.09.2004 22:51
Ja, mein Fehler, kommt davon wenn man noch schnell Kommentare hinzufügt bevor man den Code hier postet. ;)

Genau das im Quote ist nun auch im Code halbwegs, aber nicht perfekt, drin. So sollte man es definitiv nicht 1:1 verwenden, rein zum testen in der IDE gedacht:

Code:
EnableExplicit
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
  #ImportLib$ = "DXGCapx64.lib"
CompilerElse
  #ImportLib$ = "DXGCapx86.lib"
CompilerEndIf

Define cs = 0, Width.i, Height.i, buf_size.i, *buf, o_size.i, *o_bytes, *dxgi_manager
Define x = 0, y = 0, z = 0

#CR_OK = 0
#CR_ACCESS_DENIED = 1
#CR_ACCESS_LOST = 2
#CR_TIMEOUT = 3
#CR_FAIL = 4

Import #ImportLib$
  create_dxgi_manager()
  delete_dxgi_manager(*dxgi_manager)
  get_capture_source(*dxgi_manager)
  get_frame_bytes(*dxgi_manager, o_size, *o_bytes)
  get_output_dimensions(*dxgi_manager, Width, Height)
  refresh_output(*dxgi_manager)
  set_capture_source(*dxgi_manager,cs)
  set_timeout(*dxgi_manager,timeout)
EndImport

*dxgi_manager = create_dxgi_manager()

get_output_dimensions(*dxgi_manager,@Width,@Height)

Debug "w:"+Str(Width) + " h:" + Str(Height)
Debug get_capture_source(*dxgi_manager)

*buf = AllocateMemory(Width*Height*4)

Repeat
  Select get_frame_bytes(*dxgi_manager, @buf_size, @*buf)
    Case #CR_OK
      ; all ok
    Case #CR_ACCESS_DENIED
      Debug "Access Denied"
      Break
    Case #CR_ACCESS_LOST
      Debug "Access lost"
      Break
    Case #CR_TIMEOUT
      Debug "Timeout"
      Break
    Case #CR_FAIL
      Debug "General failure"
      Break
  EndSelect
Until PeekS(*buf)

CreateImage(0,Width,Height,32,RGBA(255,255,255,255))
StartDrawing(ImageOutput(0))
  DrawingMode(#PB_2DDrawing_Default)
  For y = 0 To Height-10
    For x = 0 To Width-1
      Plot(x,y,RGBA(PeekA(*buf+z+2),PeekA(*buf+z+1),PeekA(*buf+z),PeekA(*buf+z+3))) ; *buf content is in BGRA 0-255 Subpixel order
      z + 4
    Next
    Debug PeekA(*buf+z)
  Next
StopDrawing()

SaveImage(0,"DXGCap_Test_Screenshot.bmp",#PB_ImagePlugin_BMP)

delete_dxgi_manager(*dxgi_manager)

http://www.stepload.de/uploads/f1mOg_MC ... 6dYYilldF/

Die Zip Datei mit nun Dateien für 32 und 64 Bit und entsprechend die DLLs benannt, sind also neu kompiliert, wie im Code zu sehen wird automatisch die richtige Version gewählt.


Zuletzt geändert von Hoto am 04.07.2018 05:51, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: DXGI Desktop Duplication API (DX11 Win8+) Hilfe gesucht
BeitragVerfasst: 22.06.2018 09:48 
Offline
Benutzeravatar

Registriert: 01.09.2004 22:51
Nun tut sich doch noch ein kleines Problem auf:

Problem Beschreibung:

Da ich die Funktion für eine sehr Zeitkritische Sache brauche und vor der eigentlichen Verarbeitung erst mal die Daten reduzieren muss, was bei einer 4K Auflösung (also 3840x2160 * 4) stolze 31 Megabyte sind, ist nun die Frage auf welche Weise ich diese Daten am schnellsten klein kriege, also das Bild verkleinert kriege.

Da ich nur einige wenige zusammengerechnete Farben brauche, tendiere ich aktuell zu einer Auflösung von ~240x180 (könnte je nach dem ein wenig mehr oder weniger sein) zur Weiterverarbeitung der Daten, die aber nicht einfach so aus dem Bild entnommen sind sondern per #PB_Image_Smooth (oder einer ähnlich Funktion) reduziert wurden.

Die Frage ist nun welche Möglichkeiten es gäbe die Daten reduziert zu kriegen und das so schnell wie möglich, ohne Kompromisse.

Die Bilddaten bestehen einzig und allein aus den Farbinformationen in einem Speicherbereich, fangen oben links an und gehen dann Zeile für Zeile von links nach recht in der Anordnung: Blau, Grün, Rot, Alpha (also BGRA).

Bisherige Lösungsansätze

1. dem Speicherbereich einen BMP Header voran stellen, so dass das Bild direkt mit CatchImage() geladen und mit ResizeImage() verkleinert werden kann.

2. die Bilddaten direkt in den Speicherbereich eines PB Images speichern. Ob das aber besser oder gar schnell ist ohne die Daten erst umordnen zu müssen damit die Subpixel Reihenfolge passt?

3. die Daten direkt auszulesen und per Formeln verkleinern, ist da ein ResizeImage() aber nicht eindeutig schneller?

4. mir noch mal die Desktop Duplication API anzuschauen, ob die Daten nicht zuerst im Grafikkartenspeicher landen und es möglich wäre sie dort zu verkleinern. Eine Grafikkarte kann das nun mal am schnellsten.

Aktuell letzte Gedanken dazu

Mit 1. hatte ich bereits angefangen, bevor mir die restlichen Ideen kamen als ich schon im Halbschlaf war, daher muss ich mich in die Punkte noch einlesen. Vor allem 4. klingt für mich nach der eigentlich besten Lösung, allerdings müsste ich mich dann mit C++ erst mal rumschlagen, das ich gerade so halbwegs lesen kann, aber wenn ich schon mal VS C++ 2013 installiert habe... die MIT Lizenz der DXGCap.dll ließe das jedenfalls zu.

Wie würdet ihr es machen? Hab ich noch eine Methode übersehen?


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 24 Beiträge ]  Gehe zu Seite 1, 2, 3  Nächste

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.

Suche nach:
Gehe zu:  

 


Powered by phpBB © 2008 phpBB Group | Deutsche Übersetzung durch phpBB.de
subSilver+ theme by Canver Software, sponsor Sanal Modifiye