daten schnell speichern
-
Werner Salomon schrieb:
Lt. C++-Standard [...] bleibt dabei der Implementierung des konkreten Streambuf überlassen, was dann passiert!
lol, you can stop reading now. Einfach genial, dieser Standard.
Microsoft Visual Studio [...] seinen eigenen filebuf schreiben [...] OS-API [...] boost.asio [...] asynchrones Schreiben realisiert [...] nur noch durch den [...] RAM [...] begrenzt [...] overlapping IO
... was insbesondere dem OP mit seinem µC mit 600mB RAM etwas nützt.
-
hey ich hab 1GB Ram ;-).
Dachte ich zumindestfree gibt mir aus
---------------total----------used--------free---------shared---buffers----cached
Mem:-------238404------146676------91728--------0--------3752-------94296
-/+ buffers/cache: 48628 189776
Swap: 0 0 0
nur 240mB laut prozessor sollte er aber 1GB haben kann man das irgendwo einstellen.
@Werner Salomon Sorry so gut kenn ich mich nich aus
p.s. USB Stick funktioiert übrigens
-
//edit hab nicht gesehen, dass du 60fps hast.
-
Wenn du die Daten auf etwa 1/2 zusammenstauchst könntest du sie lässig über USB wegschreiben.
Umrechnen in YV12?
-
naja es geht halt gerade darum die Rohdaten zu speichern. Ich hab jetzt zumindest das RAM Problem mit nem neuen OS gelöst. geht jetzt auch um einiges schneller. Immerhin 120 Bilder am Stück mit 60fps. Bin jetzt aber leider heute noch nich dazu gekommen das mit dem Buffer zu probieren. das kommt dann morgen.
lg
Felix
-
OK.
Aber ist halt so dass das Ding - wenn ich nichts übersehen habe - keinen einzigen Anschluss hat der schnell genug wäre um die ~40 MB/s aus dem Gerät rauszubringen.(OK, der HDMI Anschluss hätte theoretisch die nötige Bandbreite, aber ich kenn leider keine HDMI-Festplatten ;-))
-
flexbex schrieb:
Ich weiss zwar nich genau welche SD Karte ich habe aber es wird keine von den Uhs sein deshalb werden die Schreibzeiten bei um die 4mb/s liegen.
Ich versuche aber 752*480*2*60fps=43mb/s zu schreiben.Es gibt SD Karten die die Geschwindigkeit schaffen. Die Frage ist nur ob dein Board es schafft.
Da ich dazu keine Specs finde, kann ich das nicht sagen.
-
flexbex schrieb:
naja es geht halt gerade darum die Rohdaten zu speichern
Dennoch kann man verlustfreie Komprimierung auf die Daten anwenden. Wenn du die Rohdaten unbedingt brauchst, kannst du sie später immernoch aus den komprimierten Daten herausrechnen.
-
YV12 ist nicht verlustfrei
Und bei verlustfrei kann man auch keine Kompressionsrate garantieren. Von daher doof, wenn das zuverlässig funktionieren soll.
-
na ok welche moeglichkeit gibt es denn. die daten lien als 10bit bayer daten da. ich wuerde im naechsten schrit mit einer ((1,2,1;2,4,2;1,2,1) maske falten um so das grauwertbild zu bekommen. ich bin offen fuer komprimierungsmethoden.d
-
Wenn du 10 Bit pro Pixel reinbekommst, dann speicher auch nur 10 Bit pro Pixel. Also aus 4 solchen Werten machst du 5 Byte. Bisschen Bits Rumschieben, mehr ist das nicht. 10 statt 16 bringt dich schonmal auf 62,5% runter.
752*480*10*60/8 Byte ~~ 27,1 MB
Das könnte sich über USB 2.0 ausgehen. Je nach Hardware und Software (OS, Treiber) schafft man effektiv so 25~35 MB/Sek.
Und natürlich kannst du versuchen verlustfrei zu komprimieren. Ist aber auch nicht ganz ohne sowas zu programmieren. Wie man es angehen kann kannst du dir beim HuffYUV CODEC abgucken.
Kurzfassung: Bild in Deltawerte (Unterschied zum vorgien Pixel) umrechnen, und diese Deltawerte dann Huffman codieren. Bzw. du kannst auch nen arithmetischen Coder einsetzen, aber das ist dann nochmal komplizierter als Huffman.Bei Bayer Daten müsstest du dabei die roten, grünen und blauen Pixel getrennt codieren. (Sonst würdest du bei farbigen Stellen dauernd unnötig hohe Deltawerte rausbekommen.)
Ein paar Tips dazu, falls du es versuchen willst:
Fertige Huffman-Libs sollte es genug geben, den Teil müsstest du also nicht selbst implementieren.
Huffman ist nicht "Byte-gebunden". Die Tatsacht dass du 10 Bit Werte hast würde dabei also nicht stören. Du baust dann einfach einen Tree auf der 1024 Symbole kodieren kann.
Beim Deltawerte Erzeugen einfach unsigned rechnen und den Wert wieder auf 10 Bit "runtermaskieren". Statt -1 speicherst du also einfach 1023. 10 + 1023 = 1033, und 1033 AND 1023 = 9. Passt also.
Du kannst dabei mit fixen Symbol-Frequenzen arbeiten. D.h. du guckst dir mal die Verteilungen (Symbol-Frequenzen) der Deltawerte an die du bei ein paar unterschiedlichen Bildern (unter unterschiedlichen Lichtverhältnissen) bekommst. Die Verteilungen summierst du einfach auf und verwendest das Ergebnis als fixen Frequency-Table. Die Kompression ist dabei natürlich nicht SO gut wie wenn du für jedes Frame den Frequency-Table neu berechnest, aber dafür muss du den Frequency-Table nicht mit abspeichern, und es spart auch Rechenzeit.
-
Was mir da einfällt ist ein separater Thread, der über eine Queue mit den Daten versorgt wird und sich um die Speicherung kümmert. Dadurch wird der Haupthread nicht blockiert.
Es würde sich auch eine schnelle Komprimierung anbieten. Wie wäre es mit LZO (http://de.wikipedia.org/wiki/Lempel-Ziv-Oberhumer). Das ist sehr schnell. Durch die Komprimierung wird die Datenmenge, die auf das Speichermedium geschrieben werden muss reduziert.
Wenn mehrere Cores zur Verfügung stehen, kann man auch die Komprimierung parallelisieren. Also statt eines Speicherthreads gleich einen Threadpool.
Und wenn die CPU-Leistung im Vergleich zur I/O Leistung sehr groß ist, dann kannst Du auch höher komprimierende Algorithmen verwenden, die mehr Rechenaufwand benötigen.
-
Ich weiss nicht ob LZO (oder andere Dictionary-basierten Algorithmen) bei Bilddaten wirklich viel Sinn machen.
Delta + Entropy-Coding funktioniert dagegen bekanntermassen gut.
Und Huffman kann man über Lookup-Tables auch richtig schnell bekommen.
-
tntnet schrieb:
Was mir da einfällt ist ein separater Thread, der über eine Queue mit den Daten versorgt wird und sich um die Speicherung kümmert. Dadurch wird der Haupthread nicht blockiert.
Es würde sich auch eine schnelle Komprimierung anbieten. Wie wäre es mit LZO (http://de.wikipedia.org/wiki/Lempel-Ziv-Oberhumer). Das ist sehr schnell. Durch die Komprimierung wird die Datenmenge, die auf das Speichermedium geschrieben werden muss reduziert.
Wenn mehrere Cores zur Verfügung stehen, kann man auch die Komprimierung parallelisieren. Also statt eines Speicherthreads gleich einen Threadpool.
Und wenn die CPU-Leistung im Vergleich zur I/O Leistung sehr groß ist, dann kannst Du auch höher komprimierende Algorithmen verwenden, die mehr Rechenaufwand benötigen.
LZO ist aber keine freie Software oder? Das sieht noch GPL aus.
-
zlib ist frei, und auch ausreichend schnell. Ist nur leider auch Dictionary-basiert.
Entropy-Coder FTW!
-
So wollte nur nochmal Feedback geben.
Also setbufs bzw setvbufs hat dann schlussendlich gereicht. Einfach nen Buffer mit 860mBytes erstellt und ich konnte 20 sekunden Aufzeichnen.
Also ich denke zur Verbesserung könnte ich jetzt noch die Threads nutzen, da ich aber eh wenig rechenleistung habe reicht es mir wenn ich die Verarbeitung am Ende mache. Naja und klar außerdem könnte ich wie noch erwähnt wurde meine 4 10Bit Werte in 5 Bytes speichern anstatt jetzt in 8. Das werd ich dann wohl machen wenn ich länger aufzeichnen will.Dankeschön aufjedenfall für die Hilfe
gruß
Felix
p.s. das mit der Komprimierung klingt interessant ist mir glaub ich gerade zu aufwendig und außerdem hab ich keine Rechenzeit übrig