video - Ist 'Android + FFMpeg' Freundschaft wirklich verfügbar?





(4)


Ich benutze http://writingminds.github.io/ffmpeg-android-java/ für mein Projekt. Es gibt einige Workarounds mit komplexen Befehlen, aber für einfache Befehle funktioniert der Wrapper sehr gut.

Die Frage bedeutet nicht, dass mich interessiert, ob ffmpeg Code auf Andoid verwendet werden kann. Ich weiß, dass es geht. Ich frage nur, ob jemand wirklich Fortschritte in Sachen Leistung gemacht hat. Ich habe die Frage nach mehreren Wochen der Experimente mit dem Zeug erstellt und ich hatte genug ... Ich möchte nicht in Branchen schreiben, in denen die Leute gar nicht sagen, welche Art von Video sie dekodieren (Auflösung, Codec) und sprechen nur über einige mystische FPS. Ich verstehe einfach nicht, was sie machen wollen. Außerdem werde ich keine Anwendung nur für mein Telefon oder für Android 2.2 ++ Telefone entwickeln, die einige erweiterte OpenGL-Funktionen haben. Ich habe recht beliebtes Handy HTC Desire, wenn die Anwendung nicht funktioniert, also was kommt als nächstes?

Nun, was habe ich?

  1. FFMpeg-Quelle aus dem letzten HEAD-Zweig. Eigentlich konnte ich es mit NDK5 nicht vergrößern, also entschied ich mich, gestohlenes zu benutzen.

  2. Das Build-Skript von bambuser (bash) mit der entsprechenden ffmpeg-Quelle ([web]: http://bambuser.com/r/opensource/ffmpeg-4f7d2fe-android-2011-03-07.tar.gz ). Es baut sich nach einigen Korrekturen gut mit NDK5 auf.

  3. Rockplayer's gelandeter ffmpeg Quellcode mit riesigem Android.mk in der Kapazität des Buildskripts ([web]: http://www.rockplayer.com/download/rockplayer_ffmpeg_git_20100418.zip ). Es baut nach einigen Korrekturen nach NDK3 und NDK5. Rockplayer ist wahrscheinlich der coolste Mediaplayer für Android und ich vermutete, dass ich einige Vorteile mit seinem Build haben würde.

Ich hatte ein passendes Video für ein Projekt (ist nicht groß und nicht klein): 600x360 H.264.

Beide Bibliotheken, die wir aus den Klauseln 2 und 3 erhalten haben, bieten uns die Möglichkeit, Frames von Video zu erhalten (Bild für Bild, Suche usw.). Ich habe nicht versucht, eine Audiospur zu bekommen, weil ich keine für das Projekt brauchte. Ich veröffentliche meine Quelle hier nicht, weil ich denke, dass das traditionell ist und leicht zu finden ist.

Nun, was sind die Ergebnisse mit Video? HTC Desire, Android 2.2 600x360, H.264-Dekodierung und -Rendering sind in verschiedenen Threads

  1. Bambuser (NDK5 Buld für armv5te, RGBA8888): 33 ms / Frame-Durchschnitt.
  2. Rockplayer (NDK3 für Neon, RGB565): 27 ms / Frame Durchschnitt.

Es ist nicht schlecht für den ersten Blick, aber denke nur, dass dies nur Ergebnisse sind, um Frames zu decodieren. Wenn jemand bessere Dekodierzeit hat, lassen Sie es mich wissen.

Das Schwierigste für ein Video ist das Rendern. Wenn wir Bitmap 600x360 haben, sollten wir eins vor dem Malen skalieren, da verschiedene Telefone unterschiedliche Bildschirmgrößen haben und wir nicht erwarten können, dass unser Video die gleiche Größe wie der Bildschirm hat.

Welche Möglichkeiten haben wir, einen Rahmen neu zu skalieren, damit er auf den Bildschirm passt? Ich konnte diese Fälle (die gleiche Telefon- und Videoquelle) prüfen:

  1. sws_scale () C-Funktion im Bambuser-Build: 70 ms / Frame. Inakzeptabel.
  2. Stupid Bitmap Reskalierung in Android (Bitmap.createScaledBitmap): 65 ms / Frame. Inakzeptabel.
  3. OpenGL-Rendering in Orthoprojektion auf texturiertem Quad. In diesem Fall musste ich den Rahmen nicht skalieren. Ich musste nur Textur 1024x512 vorbereiten (in meinem Fall war es RGBA8888) Rahmen Pixel enthalten und dann in GPU laden (gl.GTexImage2D). Ergebnis: ~ 220 ms / Frame zum Rendern. Inakzeptabel. Ich habe nicht erwartet, dass glTexImage2D nur auf Snapdragon CPU angesaugt hat.

Das ist alles. Ich weiß, dass es einen Weg gibt, um Fragment-Shader zu verwenden, um YUV-Pixel unter Verwendung von GPU zu konvertieren, aber wir werden das gleiche glTexImage2D und 200 ms nur zum Texturladen haben.

Aber das ist nicht das Ende. ... mein einziger Freund das Ende ... :) Es ist kein hoffnungsloser Zustand.

Beim Versuch, RockPlayer zu benutzen, werden Sie sich sicher fragen, wie sie diese verdammte Frame-Skalierung so schnell machen. Ich nehme an, dass sie wirklich gute Erfahrung mit ARM-Architektur haben. Sie benutzen wahrscheinlich avcodec_decode_video2 und dann img_convert (wie ich es in der RP-Version gemacht habe), aber dann benutzen sie einige Tricks (abhängig von der ARM-Version) für die Skalierung. Vielleicht haben sie auch einige "magische" Buld-Konfiguration für ffmpeg Dekodierungszeit verringern, aber Android.mk, die sie veröffentlicht haben, ist nicht die Android.mk sie verwenden. Keine Ahnung...

So, jetzt sieht es so aus, als könntest du nicht einfach eine einfache JNI-Bridge für ffmpeg bauen und dann einen echten Media Player für Android platform haben. Sie können dies nur tun, wenn Sie ein geeignetes Video haben, das Sie nicht skalieren müssen.

Irgendwelche Ideen? Ich hoffe für dich ;)




Meiner Erfahrung nach war die Konvertierung von YUV zu RGB schon immer ein Flaschenhals. Daher erwies sich die Verwendung eines OpenGL-Shaders als eine wesentliche Verbesserung.




Ich habe ffmpeg auf Android kompiliert. Von diesem Punkt an - das Abspielen von Videos ist rein implementierungsabhängig, so dass es keinen Sinn hat, Latenzen auf Dinge zu messen, die in hohem Maße an der benötigten Stelle optimiert werden können und nicht Standard-swscale verwenden. Und ja - Sie können eine einfache JNI-Bridge erstellen und sie in NDK verwenden, um ffmpeg-Aufrufe auszuführen, aber dies wäre bereits ein Player-Code.








android video ffmpeg