Hallo! Ich möchte mittels AVR auf einem Pictiva OLED-Display ein kleines Intro-Video anzeigen lassen. Wenn man das fertig programmiert hat, kann man das natürlich auch für z.B. Screensaver verwenden (bei OLED übrigens sehr vorteilhaft wegen Pixel-Verdunklung nach einer gewissen Zeit!) Ich habe mir das so vorgestellt: Verwende ein 256x64 - Display Möchte etwa 4 Sekunden mit 15 Bildern / Sekunde anzeigen --> 60 Bilder Folglich ergeben sich für die Rohdaten (4bit/px): 256 x 64 x 1/2 x 60 = ca. 490 KB Viel zu viel! Also: Video kodieren. Und ein Video-Decoder für den AVR muss her! Möglichst einfach, wenig Code, wenig RAM, wenig Rechenzeit. Nicht unbedingt soooo leistungsstark was die komprimierung angeht. Hab im Internet sehr wenig gefunden. Sogar der quasi einfachste Codec, der gut verbreitet ist, MPEG, ist schon viel zu kompliziert. Wenn ich mir dazu doc's durchlese verstehe ich nur Bahnhof... Also einen ganz eigenen Codec selbst programmieren. Mir fielen gleich ein paar Dinge ein, wo man bei Videos Daten sparen kann: Gleiche benachbarte Pixel. Dafür hab ich ein Frame (256x64) in 32x32-große "Blocks" zerlegt. Jeder Block wird einzeln und unabhängig von anderen kodiert. Ein Block kann jetzt z.B. nur Pixel mit gleicher Farbe enthalten. Habe das mit einem Test-Video gemacht: ca. 60% aller Blocks haben die gleiche Farbe. Dann gibt es Blöcke, die, wenn man sie nochmals unterteilt, teilweise ebenfalls nur aus Flächen gleicher Farbe bestehen. Dafür muss ein Block nun in etwa 4x4-große "Sub-Blocks" unterteilt werden. Soweit bin ich noch nicht mit dem Programmieren. Hab mir gedacht ich schildere euch mein Problem und vllt finden es andere hier im Board auch mal ganz interessant, einen Codec zu proggen, immerhin kann man damit einiges machen! Ich hoffe, dass ich somit ein Video von ursprünglichen 490KB auf ca. 50KB bekomme. (habe 128K Flash) Dabei muss es nicht unbedingt verlustfrei kodiert werden! (So käme man nicht sehr weit) Vielleicht haben andere hier noch Ideen, wie man einen Codec gestalten kann. MfG, Sebastian
Viele Codecs verwenden Schlüsselbilder, die die Information eines ganzen Bildes enthalten. Die nachfolgenden Bilder enthalten nur noch die Änderungen jeweils von Bild zu Bild, also deutlich weniger Information, da sich ja nicht immer alle Pixel ändern. Als Speicher käme mir da ne SD-Karte in den Sinn, der Vorteil währ dann, dass du recht einfach das Video updaten kannst. Der lesezugriff sollte schnell genug sein und die Animationslänge würde nur durch den Speicher der Karte begrenzt.
Hallo! Danke für die schnelle Antwort. Ja, ne SD kam mir auch schon in den Sinn, doch hab ich wenig Platz für sowas... Wenn dann miniSD oder so. Aber dennoch möchte ich nicht ein unkomprimiertes Video verwenden. Allein der Spaß am Programmieren ist genug was für den Codec spricht! ;-) Ja ich weiß was du meinst. I-Frames speichern ein komplettes Frame (Bild) Dazwischen lauter Frames, von denen die Änderung gespeichert wird. Quasi alle Codecs verwenden hier eine Unterteilung, so wie ich es beschrieben habe. Dadurch lassen sich zeitliche Verschiebungen "klein" kodieren: Z.B. wenn ein Text durch das Bild wandert, dann verschiebt er sich ja nur, und es kommen an einer Seite neue Pixel "herein". Es werden dann lauter Quadrate im I-Frame gespeichert, Diese können in den darauffolgenden Frames verschoben oder geändert werden. Es fragt sich nur, wieviel Rechenaufwand man dafür benötigt. Leider muss man aber im AVR die I-Frames, bzw. immer das letzte Bild merken, um das nächste Bild zu berechnen. Dafür braucht man aber 256 x 64 x 1/2 = 8KB Daten! Leider haben alle AVR's max. 4KB RAM, und für einen externen hab ich ebenfalls wenig Platz. Außerdem weiß ich nix über externe RAMS, weder wo's die gibt, wie die heißen, noch wie man die ansteuert. Deswegen denke ich, ist es die beste Lösung, wenn man nur einzelne Bilder kodiert. MfG, Sebastian
Wie wär's, wenn du nach einem key-frame die Änderungen so speicherst, wie sie übertragen werden sollen? Dann musst du nur beim "encodieren" das vorangegangene Bild im RAM halten. Ist dann natürlich nicht mehr geeignet, um live Einblendungen zu machen. Dafür müsste man natürlich doch einen Teil des Bildes im RAM halten.. Bsp: -steuerzeichen für "jetzt kommt key frame" key frame Daten -steuerzeichen für "nur änderungen" //zeile spalte byte 1 5 0xFF 5 45 0x0A 21 17 0x32 -steuerzeichen für nächsten frame
@jmoney: Bezüglich des RAMs: Naja enkodieren soll der AVR nicht können. Was soll denn der kodieren? Mir fällt keine Einsatzmöglichkeit ein. Aber machbar wäre es schon... Bezüglich den Änderungen: So ähnlich hab ich mir das auch vorgestellt. Die Änderungen würde ich allerdings so wie ich es geschrieben habe blockweise kodieren, da man sonst je Pixel viel zu viele Daten hat: 8bit Spalte + 6bit Zeile + 4bit Farbe = 18bit statt nur 4bit! Kodierung eines I-Frames UND eines Änderungsframes: I-Frame: Bild wird in beliebig große (quadratische) Blöcke zerlegt, die nicht unbedingt das gesamte Bild abdecken müssen: Leere Bereiche werden schwarz dargestellt. (Vorher einfach Bild schwarz machen, dann Blöcke draufmalen) Zwischenframes: Es werden geänderte Pixel so in Blöcke unterteilt, dass sie alle geänderten Pixel einschließen (natürlich noch ein paar andere, das schadet ja nicht...) Beim Kodieren eines Blockes würd ich das jetzt, nach nochmaligem überlegen, so machen: Erst die Position: 8bits Zeile, 4bits Spalte (bei anderen Auflösungen kann man allgemein jeweils 1Byte verwenden) Es gibt verschiedene Blockgrößen, immer Zweierpotenzen, würde spontan 2x2, 4x4, 8x8 und 16x16 vorschlagen. Dann hat man gerade mal 2bit Daten für die Größe. Dann könnte man verschiedene Farb-Modi festlegen: 2 Farben indiziert, 4 Farben indiziert, 4 Farben konstant (jede vierte), 8 Farben indiziert, 8 Farben konstant (jede zweite) und alle 16 Farben. Da es hier 6 Möglichkeiten gibt, werden hierfür 3bit benötigt. Bei indizierten Modi folgen natürlich erstmal die Farben der Palette, je Farbe natürlich 4bit. Ergeben dann nicht sehr viel Daten. 4 Farben: 2 Bytes, 8 Farben: 4 Bytes. Indizierte Paletten lohnen sich aber trotzdem erst ab größeren Blöcken. Je Pixel braucht man dann - je nach Farbmodus natürlich - 1 bis 4 bits Farbdaten. @fnah: Aha interessant... Hm... hab mich gleich mal in der Kategorie "Lossless compression algorithms" umgeschaut und bin auf den bekannten LZ77-Codec gestoßen. Der geht nach einer Methode, bei der ganze Folgen an Bytes wiederholt werden können (werden in einer Tabelle angelegt). Gibts auch im deutschen Wiki. Vielleicht wäre der ein bisschen besser, doch etwas komplizierter. Muss man sich mal näher anschauen. Ich würde aber solche RLE-Kodierungen im Nachhinein über den Bytestream laufen lassen. Beim Decoden kommt das natürlich an erste Stelle und ermöglicht hoffentlich ein reibungsloses, direktes Lesen ohne vorher alles nochmal zwischenzuspeichern. Dürfte vor allem beim PackBits kein Problem sein. Wer ist mit dran interessiert, sowas gemeinsam zu programmieren? Wenn ich fertig bin würde ich es so oder so als OpenSource veröffentlichen... Noch was: So wie es bis jetzt aussieht wird das wohl doch lossless... Muss aber nicht unbedingt sein. Wollte das nur nochmal erwähnen. Ein verlustbehafteter Codec scheint wohl nicht einfach zu sein! MfG, Sebastian
Zwar schon in etwa von Sebastian erwähnt, aber hier vielleicht noch ein hilfreicher Link der englischen Wikipedia, wo mehrere Lossless-Codecs für Videos aufgelistet sind: http://en.wikipedia.org/wiki/Lossless_data_compression#Video_compression Btw, hast du dir schonmal png-compression angeguckt?
Vor allem der erste Codec, der Animation Codec, hört sich gut an: "playback of uncompressed RGB video in real time without expensive hardware"; "uses run-length encoding"...
>@jmoney: >Bezüglich des RAMs: >Naja enkodieren soll der AVR nicht können. Was soll denn der kodieren? >Mir fällt keine Einsatzmöglichkeit ein. Aber machbar wäre es schon... Sorry, das war missverständlich ausgedrückt. Das Video wird natürlich im PC codiert. Der hat ja genug RAM.. >Bezüglich den Änderungen: >So ähnlich hab ich mir das auch vorgestellt. >Die Änderungen würde ich allerdings so wie ich es geschrieben habe >blockweise kodieren, da man sonst je Pixel viel zu viele Daten hat: 8bit >Spalte + 6bit Zeile + 4bit Farbe = 18bit statt nur 4bit! Wenn in einem Frame nur 10 Pixel geändert werden, sind das 180 bit im Vergleich zu 256 64 4 = 64kbit. Das Verfahren lohnt sich also bis 64k / 18 = 3640 veränderten Pixeln. Beim Beispiel Text durchlaufen hat man maximal 256 * 7 = 1792 für eine komplette Zeile. Bei echtem Text wird es wohl etwas weniger sein aber da stößt das Verfahren zugegebenermaßen schon an seine Grenzen. Für eine kleine Animation, wo ein Punkt durch's Bild hüpft oder sowas wäre die Kompressionsrate schon enorm hoch. Der Blockansatz lohnt sich gegenüber meinem, sobald mehr als einem benachbarte Pixel geändert werden müssen, wenn ich das richtig verstanden habe. 8-nZeile + 6-mSpalte + 2^n*2^m*4Farbe gegenüber 2^n*2^m*18 Bei n=m=1 (also Blockgröße 2x2 Pixel) braucht ein Block 30 bit (Plus 1 oder 2 weitere, wenn verschiedene Blockgrößen eingeführt werden). Klingt sinnvoll. Mit dem angesprochenen PackBits könnte man wohl aus beiden Ansätzen noch einiges mehr rausholen.
>sobald mehr als einem benachbarte Pixel
soll 2 oder mehr heißen
@Frank: Klingt nicht schlecht, bin mal das Inhaltsverzeichnis durchgegangen. Morgen hab ich mehr Zeit, da les ich mir mal einiges durch. Wird hier EIN codec vorgestellt oder allgemein Theorien zur Video-Kodierung? @jmoney: Ja soweit sind die Beispielrechnungen richtig. Ich möchte hauptsächlich 3D-Animationen (Drehungen, Bewegungen, Text, Zoomen) verwenden. Da lohnt es sich nicht, pixelweise das Bild aufzubauen. Bei einem springenden Pixel wäre das natürlich was anderes, obwohl ich genau für sowas diesen 2x2-Block einführen will, mit einem minimalen Header: da 4 Pixel recht wenig Daten gegenüber einem Header, in dem die Farbtabelle oder andere Infos gespeichert werden, recht wenig Daten brauchen, werde ich 2x2-Blöcke stets im 4bit-Modus kodieren. Somit benötigt ein einzelner einsamer Pixel ohne Nachbarn diese 14bit für die Koordinaten, den "Block-Code", also die Größe des Blocks: 2bit, und 2 Bytes für die 4 Pixel. Also 14+2+16=32bit. Auch nicht die Welt. Daher denke ich lohnt es sich kaum, 2 Kodierungsvarianten einzuführen. Würde nur den AVR-Decoder-Code aufblähen. Ich mach mich mal morgen und übermorgen ran, ein bisschen die Blocks zu coden. Ein relativ schwieriger Teil wird das Erkennen der bestmöglichsten Kodierung werden. Da mach ich es wohl so, dass hauptsächlich "rumprobiert" wird. Bei so kleinen Videos schadet es ja nicht, wenn man mit nur 1 Frame pro Sekunde kodiert... :-) MfG, Sebastian
Sebastian wrote: > Wird hier EIN codec vorgestellt oder allgemein Theorien zur > Video-Kodierung? Es wird Theora beschrieben. Hab auch nicht alles gelesen. Konnte mich nur noch an die Zerlegung in Blöcke und Unterblöcke erinnern. Da Du das auch machst, dachte ich, es hilft.
Das wird in praktisch jedem Videocoder gemacht, hauptsächlich wegen der Bewegungskompensation (welche auf dem AVR aber eher wenig Sinn macht).
Hoi,.. Es gibt noch ne andere möglichkeit,.. http://www.digitalcraft.org/?artikel_id=397 so muss man nÜx codieren und spart platz,.. (aber auch aufwendig) grüüüße
@Kai Scheddin Dir ist schon klar, dass ich dann eine Grafikkarte mit OpenGL oder DirectX, einen Prozessor mit >500MHz und viiiiiiiel RAM (ca 200MB) brauche? Das wäre die wohl sinnloseste "Kodierung" eines Films. Das sind gar keine kodierte Videos sondern 3D-Animationen, d.h. ein ausführbares Programm mit lauter Koordinaten, Farbmuster, Sample-Musik usw. die alle erstmal Daten für Texturen, Objekte und die Musik generieren müssen und dann noch von OpenGL oder DirectX dargestellt werden müssen... Aber trotzdem Danke...
Eins der größten Probleme sind wenn ichs recht verstanden habe einfach der Platz. Ram anhängen an den AVR ist im Prinzip nix wildes, hab mal nen SIMM30 EDO angepfriemelt mit 1MB, das funzt prima, aber der Riegel muss halt irgendwo hin und wenns für nen SD-Chip nicht reicht gehts scheinbar schon eng zu. Die einzige Möglichkeit, die ich sehe währe n µC verwenden, der eben intern entsprechend RAM vorrätig hat, aber beim AVR wird man mit mehr als 8K RAM kaum fündig werden (hab da aber auch nicht alle Typen im Kopf, lass mich gern belehren) Ich seh da eher den Weg in ARM weisen ... hätt dann auch was Rechneoperationen angeht mehr Power.
Marko wrote: > Viele Codecs verwenden Schlüsselbilder, die die Information eines ganzen > Bildes enthalten. Die nachfolgenden Bilder enthalten nur noch die > Änderungen Das mit den Änderungen ist richtig, das mit den Schlüsselbildern nicht. MPEG und Konsorten verwenden eine sog. Bewegungsprädiktion, d.h. sie versuchen das aktuelle Bild aus dem Vorgängerbild zu prädizieren (im einfachsten Falle durch zusammenpuzzeln aus Blöcken) und übertragen dann nur das JPEG-codierte Differenzbild. Selbst wenn er eine Transformationscodierung und eine Bewegungsprädiktion macht fehlt aber noch ein Entropiecodierer, der die eingesparte Redundanz/Irrelevanz auch wirklich einspart! Mein Vorschlag wäre als "Brutallösung": Bitauflösung durch entsprechende Quantisierung reduzieren. Wenn er mit 4 Farben auskommt kann er 4 Pixel in einem Byte unterbringen.
@Sebastian Ja, das ist es,.. der gedanke daran animationen zu basteln ist nicht so abwägig, besonders in der kategorie "RESTRICTED",.. Da reichen simple graphic lbr'S aus um ein >>INTRO zu erzeugen,.. und man braucht keine 500Mhz und 3DHard Render engine,.. wie es z.B. http://thomaspfeifer.net/ Da guckst du einfach unter AVR-Projekte -> Ansteuerung eines NOKIA LCD,.. Dort wird deutlich was man mit einem avr schickes machen kann,... besonders dieses bild macht es deutlich: http://thomaspfeifer.net/nokia_display_4.jpg => Demos als intro ist eine gute lösung ansonsten (wie oben vlt. schon erwähnt) RLE codierung, oder bei 25 frames/s alle 5 frame einen keyframe mit 5 bit abstand und der rest wird mit 3D interpoleration getätigt,.. is nur ne idee,.. grüüße ______________________________________________________________________ ___ edit: die 5 bit abstand sollten möglichst in abs. position inc. bzw. dec. um ein gut möglichstes ergebnis zu erhalten,...
Evtl reichen für ein Intro auch 5 Bilder/s und als kopdierung animated GIF.
5 frames pro sekunde? Da kann man ja den Pixeln wortwörtlich hinterherschauen... Neenee wenn schon denn schon. Anscheinend glaubt hier niemand dass man das so "einfach" hinbekommt?!?!?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.