Daniel Thoma: Bild ständig aktualisieren

Beitrag lesen

Hallo Stefano,

Hast Du jemals intensiver mit Java gearbeitet?

Das habe ich sehr wohl.

Was haben wir vergessen? Stimmt! JFrame! Will der Host anspruchsvollere Aktionen, beispielsweise pixelorintierte Manipulation vornehmen, so muss er das Image-Objekt zuvor über die Instanzmethode "createImage" von JFrame kopieren, und einem BufferedImage übergeben!

Wieso sollte hier mit Swing rumbasteln? Ein BuffedImage hat eine Methode um ein Graphics2D Objekt zu beziehen und darin rumzumalen. Das kann ich dann mit javax.imageio.ImageIO.write(...) irgendwo hin schreiben.

Insgesamt ist das eine durchaus schaffbare Sache, auch, wenn es 5, 10, oder gar 20 Mal in der Sekunde gemacht werden soll. Aber dann soll noch ein Client per HTTP darauf zugreifen. Mhhhh schafft der das auch 8 mal in der Sekunde? Und was ist mit 100 Clients?

Nun, das stellt natürlich dann gewisse ansprüche an den Webserver. Über 100 Gleichzeitige verbindungen 8 Bilder/Sekunde rauszuschieben muss er packen. Die Bilder dürfen sicher nicht sehr groß sein, sind sie aber anscheinend auch nicht.

Der Handshake passiert beim Verbindungsauf- und -abbau.

Ok beim Abbau passiert ein Bisschen was anderes, wichtig ist, für die Übertragungsgeschwindigkeit ist es irrelevant.

Wieso verwenden HTTP und FTP TCP?

Zumindest möchten beide Protokolle, dass ihre Datentransfers korrekt sind.
Richtig, es sollen _alle_ Daten in der richtigen Reihenfolge ankommen. Mit sensiblen Daten hat das erst mal nichts mehr zu tun. Auch ein Bild oder ein serialisierte Java-Objekt kann man wegwerfen, wenn ein Paket fehlt und man muss die Reihenfolge kennen. Wenn man also UDP verwendet, muss man die Daten in einer Form übertragen, in der auch einfach mal ein Paket weg fallen kann.
Das ist bei Java-Objekten garantiert _nicht_ der Fall.

Insgesamt scheint TCP jedoch Einiges zu tun zu haben, bis die Daten gesendet oder erhalten sind, im Gegensatz zu UDP, bei dem diese Meschanismen fehlen.

Stimmt, aber sobald deine Daten nicht mehr in ein Paket passen, brauchst Du diese Mechanismen.
Allen gemeinsam dürfte sein, dass der Aufwand, der Betrieben wird, um Objekte zu serialisieren und zu deserialisieren größer ist.
UDP ist in dem Fall höchstens dann interessant, wenn man will, dass bei langsamen Verbindungen noch ein Teil der Daten ankommt. Mit diesem Teil der Daten muss man dann aber auch noch was vernünftiges machen können. Das zu erreichen bedarf einiges an Überlegung.

Allerdings. Und Bildchen, die die Maße von 500 x 500 wohl nicht übertreffen, zudem vermutlich noch als JPG vorliegen, sind keine großen Datenmengen.

Es liegt aber nicht als JPG vor, wenn Du Objekte serialisierst wie vorgeschlagen. Und selbst wenn Du es in UDP Pakete rein bekommst, entsteht dadurch höchstens dann ein vorteil, wenn die Verbindung zu langsam ist, um alles zu übertragen. Das ist aber nicht das, was Du gesagt hast. Deine Aussage war "TCP ist langsam weil 3-Wege-Handshake".

Wahrscheinlich hast Du auch keine Erfahrung mit Serialisierung in Java.

Zweite Überraschung: die habe ich auch.

In BufferedImage sind über 60% der Attribute als transient deklariert.

Interessante information. Nach einem Blick in den Quellcode sehe ich allerdings, dass gar nichts als transient deklariert ist.
Dafür hängen schon mal 4 weitere Objekte (ColorModel, WritableRaster, OffScreenImageSource und eine Hashtable) dran, die natürlich mit serialisiert werden. WritableRaster referenziert dann ein DataBuffer, der irgendwie die Bilddaten in einem Array speichert. transient ist da auch wieder nix. Außerdem hängen überall noch verschiedene, weitere Objekte dran. Ich hab' das jetzt nicht alles verfolgt.

Es werden nur das Array für die Bitweise Verarbeitung der Pixel

Das dürften 3 Byte / Pixel sein. Also alles andere als eine optimale codierung.

Ist prinzipiell nicht anderes, als mein Vorschlag. Für den Videostream würde ich gerne eine entsprechende Bibliothek sehen.

< http://java.sun.com/products/java-media/jmf/2.1.1/formats.html> erlaubt schon mal AVI zu erzeugen. Ich weiß nicht, wie gut das ist, aber da ist eben etwas experimentieren und recherchieren angesagt.

Zum Schluss noch mal zur "Pauschalität" von langsamen Java-Applikationen (mit Bezug auf die Antwort der Hosts). Mir ist sehrwohl bewusst, dass Java in vielen Bereichen immer schneller wird, allerdings nicht sämtlichen.

Meistens ist es das Wert. Das es Fälle gibt, in denen Java nicht geeignet ist, ist klar. Für sehr viele Anwendungen gilt das nicht, für diese wahrscheinlich auch nicht.

1.) Iterieren durch eine ArrayList mit 1.000.000 Einträgen ist etwa 15 % langsamer, als ein vergleichbares Konstrukt in C++, dass ich selbst erstellt habe (ebenfalls ArrayList getauft). Und dabei hätte das durchaus performanter sein können!
2.) Mein persönlicher Vergleich zu Javas ServerSocket + Socket (TCP-Sockets) und dem WinSock in C/C++ ergab, dass die nahezu identisch aufgebauten Java- und C++-Applikationen Geschwindigkeitsdifferenzen von bis zu 400 Millisekunden hatten (Java war langsamer)! Und das ist enorm!

Mag sein. Solcher Benchmarks sind aber immer mit vorsicht zu genießen, vor allem wenn man den Quelltext nicht gesehen hat.
Iterieren über eine ArrayList ist im wesentlichen Iterieren über einen Array. Das das deutlich langsamer in Java als in C++ ist, erscheint merkwürdig. Auch bei den Sockets ist das etwas merkwürdig. Die Java-API verwendet ja intern auch nix anderes.

wieso werden Videos auf Datenintegrität und Sequenzreihenfolge geprüft?

Weil der Videodecoder korrekte Daten in der richtigen Reihenfolge benötigt, wenn man keine spezielle Codierung verwendet. Ob Passwörter o.ä. sicherheitsrelevante Daten Übertragen werden, hat mit TCP nichts zu tun.

ARD scheint die Streams per HTTP zur verfügung zu stellen. Ich hab' das jetzt allerdings nicht auseinandergepfückt.

Grüße

Daniel