Na ist ja schön zu sehen, dass hier nach einem provokanten Bild doch noch ein bisschen was los ist
Um erst einmal den Haken an der Sache anzusprechen: ohne iOS 8 könnt ihr diese Latenzen aller Voraussicht nach vergessen. Erst mit iOS 8 ist es möglich, den Hardware-Decoder 'direkt' zu nutzen. Vorher wurden natürlich das Abspielen von Videofiles usw. auch beschleunigt, aber das direkte Füttern mit eigenen Daten ging nicht (oder zumindest nicht ohne irgendwelchen weiteren Tricks, die sehr aufwendig werden dürften). Mir ist jedenfalls nichts dergleichen bekannt.
Das erst einmal als Schock am Anfang. Jetzt vielleicht noch ein bisschen mehr Hintergrund: Als aller erstes hatte ich eine ganz einfache GStreamer Pipe mit Softwaredecoder laufen, was an sich auch funktioniert hat. Die Latenz war so um die 140 ms herum. Allerdings fiel mir auf, dass die CPU bei 1080p30 und etwas höheren Bitraten gut ins Schwitzen kam. War die Datenrate zu hoch (auf meinem Device bei 1080p30 war das irgendwas über 600 kBit/s), kam es auch zu Bildfehlern, weil die CPU schlichtweg nicht hinterher kam. Ähnlich sah es auch bei 720p49 aus. Da mir das nicht ganz so gefallen hat, und ich auch Wind davon bekommen hatte, dass ab iOS 8 der HW-Decoder frei zugänglich gemacht worden ist, habe ich mich direkt mal daran gemacht, die Daten in GStreamer abzuzapfen und durch den HW-Decoder zu schieben. Das wollte erst nicht so recht (siehe
hier) und ungefähr gleichzeitig hatte einer der Core Developer in seinem
Blog verkündet, dass nun auch GStreamer direkt die HW-Decodierung unterstützt. Das kam mir also recht passend und ich habe es dann auch irgendwann soweit laufen gehabt, nachdem noch einige Bugs im Head-Branch behoben werden mussten, damit die Cross-Kompilierung keine Probleme mehr machte. Soweit so gut, also nichts wie ausprobieren: Und siehe da, die CPU-Last war auf die Hälfte gesunken, und es gab keine Bildfehler bei höheren Bitraten mehr. Blöderweise hat das ganze eine erhebliche Latenzsteigerung mit sich gebracht, und es waren meist so um die 300 ms. Also war der Ansatz gut, aber irgendwas noch nicht effizient. Mein nächster Schritt war es deswegen, GStreamer komplett rauszuschmeißen, und selbst das bisschen RTP Depacktization zu machen. Durch die offene und gute Dokumentation dazu (insbesondere natürlich
RFC6184) lief auch das irgendwann und ich konnte die NALUs in den HW-Decoder schubsen. Damit liegt die CPU-Last nun nur noch bei 25% und die Latenz habt ihr ja gesehen
Nun werde ich mal noch einige Komfortfunktionen zu Ende basteln (also Auflösung, Framerate etc. in der App über Sledge's Webserver einstellen), um dann alles mal ausführlich testen zu können.
Fürs Erste soll es das an Einblicken gewesen sein. Jetzt würde mich mal noch interessieren, ob jemand von den Android-Fanatikern hier genaueres zu der Decodierung auf seiner Platform sagen kann (also HW oder SW) und wie die Single-Core-Auslastung so ist?! Oder läuft GStreamer auf Android sogar multithreaded? Ich hab keine Ahnung...
Und was ich eben mit den Rahmenbedingungen für die Latenzmessungen meinte, war eher weniger die WLAN-Strecke, als viel mehr Auflösung, Framerate etc. Außerdem stelle ich immer wieder fest, dass das Verfahren mit der Stoppuhr auf dem Bildschirm eher semigut geeignet ist; es gibt einfach zu viele Unbekannte (Rendering-Framerate von Javascript im Browser (zumindest wenn man die Stoppuhr im Browser laufen lässt ^^)). So habe ich auch eine Messung, wo ich einmal eine Latenz von
44 ms habe, und eine Bildschirm-im-Bildschirm-Ebene tiefer auf 130 ms komme. Es war also innerhalb von Bruchteilen einer Sekunde und eine Schwankung der realen Latenz um den Faktor 3 halte ich dann doch für sehr unwahrscheinlich. Und das habe ich nicht nur einmal beobachtet, sondern mehrfach. Falls also jemand eine bessere Idee hat, wie man das vernünftig ermitteln könnte, immer her damit. Ich habe auch schon an so eine LED-Wand gedacht, wie sie für Auslöseverzögerungsmessungen von Kameras verwendet werden, aber extra dafür eine bauen ist wohl doch zu aufwendig. Zumal Vergleiche damit auch nicht besser gehen, falls nicht noch jemand so eine baut
Um alle Nichtleser meines Beitrags noch ein bisschen zu schocken, hänge ich mal noch die oben geschilderte Messung an
Edit: Bild nachgereicht.