Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 18, 2025 08:07

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 12 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: glReadPixels Bitmap komprimieren
BeitragVerfasst: Mo Jul 07, 2008 11:29 
Offline
DGL Member

Registriert: Do Mär 17, 2005 20:43
Beiträge: 26
Hallo

Ich schreib mir ein Tool mit dem ich aus Spielen Video und Audio aufnehmen kann.
Das Problem sind hierbei vor allem die übergroßen Bitmaps die ich mit glReadPixel bekomme.

Ich benutze momentan "GL_BGRA" um die Bilder einzulesen.
25 Frames sollten es schon werden um ein Video zu erstellen.
Spiele haben aber sehr häufig große auflösungen und ich hab dann gut 10 MB+ große Bitmaps.

10 MB x 25 = 250 MB pro sekunde.

Jetzt suche ich eine Methode um die Bitmaps möglichst schnell - also in echtzeit ( 25 frames ) so zu verkleinern, dass ich diese auf die Festplatte schaufeln kann.

Eine dirrekte Video komprimierung ist denke ich ausgeschlossen - das geht nicht schnell genug.
Also möglichst kleine Bildformate erstellen und auf die festplatte speichern schein die einzig lösung zu sein ( bei entsprechend kleinen Bildern vielleicht auch im speicher halten ).

Gibt es eine Möglichkeit die bitmaps vielleicht als 16 bit zu bekommen ( kleiner ) oder ein resize durchzuführen?

Oder hat jemand eine idee zu der Problematik?

lg
Arnulf


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jul 07, 2008 11:44 
Offline
DGL Member

Registriert: Fr Dez 28, 2007 20:24
Beiträge: 62
Wohnort: Berlin
Ich hab ein ähnliches Programm geschrieben, es hat halt je nach FPs vom Programm mehrere Screenshots erstellt und diese dann in eine AVI gespeichert. Ich habe das Problem gelöst indem ich die Bitmaps erst in Jpeg umgewandelt habe.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jul 07, 2008 12:52 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 31, 2007 18:32
Beiträge: 150
Programmiersprache: Pascal
Ich würd erstmal den Alphakanal nicht mitspeichern...das dürfte auch ein bisschen was einsparen..oder brauchst du den für irgendwas??


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jul 07, 2008 13:02 
Offline
DGL Member

Registriert: Do Mär 17, 2005 20:43
Beiträge: 26
@FrenK
da war ich mir nicht sicher, was glreadpixel macht wenn ich nur GL_BGR hole und nicht GL_BGRA
aber das hätte ich schon noch ausprobiert, dann hätte ich mal 24 bit bitmap :)
gut wäre eben 8 oder 16 bit was für so ein video vermutlich ausreichend wäre.
( komprimiert dann gleich mal auf die hälfte oder 1/4 ).

@Jerk
wie hast du die Avi aufnahme gemacht? mit einer komponente - ich wollte mir gerade aviwriter anschauen.
dspack soll das auch können... welches hast du verwendet?
und hast du audio vom mixer aufgenommen ( das hätte ich geplant ).

was die frames betrifft, so hoffe ich doch das das spiel mit mindestens 25 fps läuft - das hol ich mir momentan vom game.

lg
Arnulf


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jul 07, 2008 13:12 
Offline
DGL Member

Registriert: Fr Dez 28, 2007 20:24
Beiträge: 62
Wohnort: Berlin
Meine erste Unit hatte ich von hier:
http://www.delphipraxis.net/topic10922.html

die funktionierte aber nicht sonderlich toll, deswegen habe ich ne andere genommen und modifiziert, ich versuch mal rauszufinden woher die war bzw meine alte Festplatte zu durchforsten.


*edit* Glück gehabt


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jul 07, 2008 13:24 
Offline
DGL Member

Registriert: Do Mär 17, 2005 20:43
Beiträge: 26
ja hab etwas ähnliches gewollt und diese componente bekommen:
http://www.delphipraxis.net/topic131997 ... highlight=
ob das allerdings gut funktioniert werde ich erst ausprobieren müssen.

bei deinen units - welche verwendest du?
und gibts eine anleitung bzw. ein beispiel dazu, oder muss man sich durch die sourcen lesen um sich auszukennen ?

momentan hab ich einen multimediatimer der mir immer ein bitmap vom game liefert ( frame genau ).
dachte nicht, dass ich onthefly hin bekomme bei der framerate ... aber mal probieren.
und audio kann ich als wave hinzufügen oder geht das auch dirrekt von einem stream?.

lg
Arnulf


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jul 07, 2008 13:33 
Offline
DGL Member

Registriert: Fr Dez 28, 2007 20:24
Beiträge: 62
Wohnort: Berlin
Also einbinden ins projekt musst du nur AVICompression, aber diese muss wissen wo die anderen beiden units sind.

Code:
  1.  
  2. uses AVICompression;
  3. ...
  4.  AVIOptions                 : TAVIFileOptions;
  5. ...
  6.  AVICompressor          := TAVICompressor.Create;
  7.  
  8. ...
  9.    with AVIOptions do
  10.    begin
  11.     Init;
  12.     Width                := rWidth;
  13.     Height               := rHeight;
  14.     FrameRate            := 25;
  15.     Name                 := 'one';
  16.     Handler              := 'XVID'; // 'MSVC'
  17.     Quality              := 10000
  18.     KeyFrameEvery        := 1
  19.     BytesPerSecond       := 0
  20.     Compress             := true;
  21.     ShowDialog           := false;                                                // Kannst ja mal auf True setzen.
  22.    end;
  23. ...
  24.  
  25.  AVICompressor.Open(Filename,AVIOptions); // Erstellt Datei
  26.  
  27. ...
  28.  
  29.  AVICompressor.WriteFrame(Picture);  //Für jeden screenshot einmal aufrufen
  30.  
  31.  
  32. ...
  33.  AVICompressor.Close;
  34.  


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jul 07, 2008 14:17 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 31, 2007 18:32
Beiträge: 150
Programmiersprache: Pascal
ich wüsste wie du von 32 bit auf z.b 16 bit kommen könntest diese BMP wären dann jedoch nich mehr von anderen Programmen als BMPs zu lesen und es würde Farbverlust zur Folge haben wenn dir das nichts ausmacht :

R = 255 = 11111111
G = 255 = 11111111
B = 255 = 11111111
A = 255 = 11111111

R / 255 * 15 = 15 = 00001111
G / 255 * 15 = 15 = 00001111
B / 255 * 15 = 15 = 00001111
A / 255 * 15 = 15 = 00001111

CompRGB(16bit) = R + B shl 4 + G shl 4 + A shl 4;

R0000000000001111
G0000000011110000
B0000111100000000
A1111000000000000

CompRGB(16bit) = 1111111111111111

R = (CompRGB(16bit) and $03) = 1111
G = (CompRGB(16bit) and $07) shr 4 = 1111
B = (CompRGB(16bit) and $0B) shr 8 = 1111
A = (CompRGB(16bit) and $0F) shr 12 = 1111

breichtigt mich wenn ich mich irre aber ich meine so müsste es stimmen


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jul 09, 2008 13:04 
Offline
DGL Member

Registriert: Do Mär 17, 2005 20:43
Beiträge: 26
Ok - naja ich hab momentan den alpha channel weg gelassen
also 24 bit.

jetzt versuche ich mal ein live encoding zu einem avi.
ob ich die 24 bit noch in 16 bit umwandle ist fraglich - muss ich ausprobieren ob es geschwindigkeitsmäßig etwas bringt.
wenn ich dein posting vertstehe machst du einfach ein left shift und benutzt einfach die msg (most significant bits ) für die Farben.

also würde ich bei 24 bit einfach 3 mal shiften.
aber warum sollte das dann nicht mehr lesbar sein von einem standardprogramm? - wenn ich den header auf 16 bit anpasse müsste es doch wieder stimmen.

Die Frage ist allerdings auch was passiert wenn ich live avi encode, macht es einen unterschied ob ich 24 bit oder 32 bit habe?
na jedefalls werde ich es ausprobieren ...

sollte es noch ideen geben wie man sowas am bessten angeht dann immer her damit.

wenn ich statt live avi encoden die bildaten auf die festplatte speichern will, müsste ich wirklich ordentlich komprimieren.
500 kb * 25 = 12500 kb also 12 mb.
nur wird das auch nicht gehen - vermute ich ... na ich werde berichten.

ausserdem fehlt mir bei der unit von Jerk noch audio.

lg
Arnulf

Edit:

leider bekomme ich ständig access violations wenn ich AVICompressor.WriteFrame(myBitmap);
aufrufe

Code:
  1. procedure CreateAviCompressor;
  2. begin
  3. AVICompressor := TAVICompressor.Create;
  4. end;
  5.  
  6. procedure InitAviOptions;
  7. begin
  8.      with AVIOptions do
  9.      begin
  10.           Init;
  11.           Width := 800;
  12.           Height := 600;
  13.           FrameRate := 25;
  14.           Name := 'myavi';
  15.           Handler := 'XVID'; // 'MSVC'
  16.           Quality := 10000;
  17.           KeyFrameEvery := 1;
  18.           BytesPerSecond := 0;
  19.           Compress := true;
  20.           ShowDialog := false; // Kannst ja mal auf True setzen.
  21.      end;
  22. end;
  23.  
  24. procedure TfVideo.CreateAvi(name : string);
  25. begin
  26.      CreateAviCompressor;
  27.      InitAviOptions;
  28.      AVICompressor.Open('myavi',AVIOptions); // Erstellt Datei
  29. end;
  30.  
  31. procedure TfVideo.CloseAvi;
  32. begin
  33.      AVICompressor.Close;
  34. end;


und danach mit meinem bitmap der call auf AVICompressor.WriteFrame(myBitmap);
die bitmap wird richtig angezeit im delphi auf einem pannel oder auf der hauptform - also denke ich, dass das bitmap ok ist.

access violation bekomme ich hier :
Code:
  1. Result:=AVIStreamWrite(CompStream,StreamSize,1,Bitmap.ScanLine[Bitmap.Height-1],Bitmap.Width*Bitmap.Height*Sze,0,@SamplesW,@BytesW);

in avifil32.dll


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jul 09, 2008 23:38 
Offline
DGL Member
Benutzeravatar

Registriert: So Jun 04, 2006 12:54
Beiträge: 263
naja das mit dem komprimieren ist so eine sache. In der regel kann man davon ausgehen das man ungefähr die 1080p HDTV auflösung verarbeiten kann. Im schlimmstem fall einfach 1920x1200, so das ein frame 2,3 MPixel hat. mit 4 multipliziert passen die 10 mb zwar, aber es gäbe eine ander strategie um die daten schnell zu komprimieren:

Render stat in den back buffer in ein FBO und kopier es dann in einen backbuffer, oder kjopüier den backbuffer in eine textur.
Benutz eine weitere textur mit voller auflösung und berechne mit einem einfachem shader den luminance Anteil.
Zwei weitere texturen mit je hablierte höhe und breite nehmen die farbanteile auf.
Alle 3 texturen mit hilfe von PBOs von der GPU herunterladen (3,4 MB pro frame) Das ist immerhin schon im geschwindigkeitsbereich eines schnellem raid 0. Teil weise lasen sich diese YUV bilder direkt in die nächsten encoder stufen einspeisen.

Als schnelle variante wäre es noch denkbar die bilder auf der GPU per DCT zu encodieren, so das auf der CPU nur noch die letzten schritte für eine jpg encodierung notwendig wären. Solang dort die kompression bei 1:10 belassen wird ist es recht verlustarm.

Genauso gut wäre es möglich die wavelet transformation von jpeg2000 (welches ebenfalls als motionjpeg2000 verwendbar ist) allerdings dürfte der letzte schritt sich noch schlechter aus vorhandenen jpg200 biblioteken übernehmen lassen

eine ander variante wäre es auf einer 4 kern CPU mit 3 jpg encodern zugleich zu arbeiten, welche dann immer abwechselnd in threads ein frame verarbeiten. (der 4. kern bleibt für das game)

Wenn das alles zu viel ist: Die halbe Auflösung tut es meist auch.....

_________________
Lumina plattform unabhängige GLSL IDE


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jul 10, 2008 09:24 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 31, 2007 18:32
Beiträge: 150
Programmiersprache: Pascal
Das Problem könnte darin bestehen das die Programme 16bit anders abspeichern als wie ich es vorgeschlagen habe...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jul 11, 2008 21:59 
Offline
DGL Member

Registriert: Do Mär 17, 2005 20:43
Beiträge: 26
Also ich bin wirklich am ende meiner künste.
@oc2k1 tut mir leid aber davon verstehe ich zu wenig :)
aber ich kann nachvollziehen was du meinst.

@FrenK Ja stimmt schon ich glaube bei bitmap sind 5 bit rot 5 bit grün und 6 bit blau - aber das lässt sich schon lösen.

@Jerk - tut mir leid ich hab es nicht zum laufen gebracht.

Jedenfalls hänge ich mal ein versuchsprojekt als attachement an.

Hier handelt es sich um ein einfaches Projekt das auf 4 verschiedene arten versucht aus bitmap ein avi zu erstellen.

Form1:
Hier wird AviWriter_2 verwendet - das funktioniert - ich hab dafür 3 buttons verwendet ( testhalbe ) man muss die 3 nur durchklicken von oben nach unten
Form2:
Hier gibt es 2 Buttons es wird AviWriter_2 verwendet
1. Timer: hier verwende ich einen Multimedia Timer - es funktioniert nicht, weil der timer in einem Thread läuft
2. Thread: zum testen obs am thread liegt hab ich das gleiche nochmal ohne timer nur mit einen thread gemacht.- verwendet unit3
Form4:
Hier verwende ich AVICompressor von Jerk - ohne thread und timer schein es wenigstens zu laufen, aber leider erstellt der nur sinnlose bilddaten.

Ohne Thread hat das aber alles keinen sinn, weil ich ja gleichzeitig von den daten aus dem spiel warten muss.

Hier bekommt man das ganze test projekt mitsamt aller komponenten die man braucht.
Ebenfalls sind 10 Bitmaps dabei die ein Video werden sollten.

http://rapidshare.com/files/128980658/bmptoavi.rar

Vielleicht kann mir jemand helfen und mir sagen was hier falsch läuft.
Wäre wirklich nett, weil ich jetzt schon eine ziemliche weile daran herum-verzweifle.

lg
Arnulf


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 12 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 7 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 15 Queries | GZIP : On ]