www.mikrocontroller.net

Forum: Mikrocontroller und Elektronik AVR: Video-Codec für kleines Intro oder Screensaver

Autor: Sebastian (Gast)
Datum: 23.06.2007 14:21

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
Autor: Marko (Gast)
Datum: 23.06.2007 14:29

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.
Autor: Sebastian (Gast)
Datum: 23.06.2007 14:41

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
Autor: jmoney (Gast)
Datum: 23.06.2007 14:54

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
Autor: fnah (Gast)
Datum: 23.06.2007 14:58

sehr einfach und schnell zu decodieren:
http://en.wikipedia.org/wiki/PackBits
Autor: Sebastian (Gast)
Datum: 23.06.2007 18:16

@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
Autor: Simon K. (simon) Benutzerseite
Datum: 23.06.2007 18:38

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_compres...

Btw, hast du dir schonmal png-compression angeguckt?
Autor: Sebastian (Gast)
Datum: 23.06.2007 18:58

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"...
Autor: jmoney (Gast)
Datum: 23.06.2007 19:07

>@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.
Autor: jmoney (Gast)
Datum: 23.06.2007 19:09

>sobald mehr als einem benachbarte Pixel

soll 2 oder mehr heißen
Autor: Frank Jonischkies (frajo)
Datum: 23.06.2007 20:23

Das mit den Blöcken klingt fast wie theora. Kennst Du das?
http://theora.org/doc/Theora_I_spec.pdf
Autor: Sebastian (Gast)
Datum: 23.06.2007 20:57

@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
Autor: Frank Jonischkies (frajo)
Datum: 23.06.2007 21:25

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.
Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite
Datum: 23.06.2007 21:35

Das wird in praktisch jedem Videocoder gemacht, hauptsächlich wegen der
Bewegungskompensation (welche auf dem AVR aber eher wenig Sinn macht).
Autor: Kai Scheddin (zeusosc)
Datum: 23.06.2007 21:49

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
Autor: Sebastian (Gast)
Datum: 24.06.2007 17:35

@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...
Autor: Marko (Gast)
Datum: 24.06.2007 17:58

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.
Autor: Rüdiger Knörig (Firma TU Berlin) (sleipnir)
Datum: 25.06.2007 18:38

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.
Autor: Kai Scheddin (zeusosc)
Datum: 25.06.2007 23:38

@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,...
Autor: Obelix (Gast)
Datum: 26.06.2007 09:18

Evtl reichen für ein Intro auch 5 Bilder/s und als kopdierung animated
GIF.
Autor: Sebastian (Gast)
Datum: 27.06.2007 11:07

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?!?!?

Antwort schreiben

Die Angabe einer Email-Adresse ist freiwillig. Wenn Sie automatisch per Email über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
  • Aussagekräftigen Betreff wählen
  • Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
  • JPEG-Dateien (.jpg) nur für Fotos und Scans verwenden
  • Schaltpläne, Screenshots usw. als PNG oder GIF anhängen

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel





Hinweis: der Originalbeitrag ist mehr als 6 Monate alt.

webmaster@mikrocontroller.netImpressumWerbung auf Mikrocontroller.net