Verwenden MediaCodec für H264-streaming
Ich versuche momentan die Verwendung von Android als Skype-Endpunkt. In dieser Phase brauche ich zum codieren von Videos in H. 264 (da es die einzige unterstützte format von Skype) und die Kapseln mit RTP, um die streaming-Arbeit.
Offenbar die MediaRecorder
ist nicht sehr geeignet für diese aus verschiedenen Gründen. Einer ist, denn er fügt MP4-oder 3GP-Header, nachdem es fertig ist. Ein anderes ist da um zu reduzieren die Latenz auf ein minimum, hardware-Beschleunigung kann in handliches kommen. Das ist, warum ich mag würde, um die Verwendung der jüngsten low-level-Funktionen für das framework, als MediaCodec
, MediaExtractor
usw.
Im moment Plane ich auf der Arbeit wie folgt. Die Kamera schreibt Ihre Videos in einen Puffer. Die MediaCodec enkodiert das video mit H264 und schreibt das Ergebnis in einem anderen Puffer. Dieser Puffer ist zu Lesen von einem RTP-encapsulator, was sendet der stream-Daten an den server. Hier ist meine erste Frage: ist dieser plan klingt machbar für Sie?
Nun bin ich bereits fest mit dem ersten Schritt. Da alle Unterlagen im internet zum verwenden der Kamera verwenden der MediaRecorder
ich finde keine Möglichkeit zum speichern der raw-Daten in einen Puffer, bevor die Codierung. Ist addCallbackBuffer für diese geeignet? Hat jemand einen link mit einem Beispiel?
Weiter, ich kann nicht finden, eine Menge an Dokumentation über MediaCodec (da es ziemlich neu). Wer hat ein solides tutorial?
Schließlich: alle Empfehlungen auf den RTP-Bibliotheken?
Vielen Dank im Voraus!
Du musst angemeldet sein, um einen Kommentar abzugeben.
UPDATE
Ich war endlich in der Lage zu erstellen, die richtigen RTP-Pakete aus den h264-frames. Hier ist, was Sie im Auge zu behalten (es ist eigentlich ganz einfach):
Den encoder erzeugt NAL-Header für jeden einzelnen frame. Aber es gibt jeden frame als h264 bytestream. Dies bedeutet, dass jeder frame beginnt mit drei 0-bytes und 1 byte. Alles, was Sie tun müssen ist, entfernen Sie die start-Präfixe, und setzen Sie den Rahmen in ein RTP-Paket (oder teilen Sie Sie mit FU-Wie).
Nun zu deinen Fragen:
Sollten Sie die Verwendung der Kamera.setPreviewCallback(...), und fügen Sie jeden frame, um den encoder.
Dies sollte eine gute Einführung, wie die MediaCodec funktioniert. http://dpsm.wordpress.com/2012/07/28/android-mediacodec-decoded/
Ich bin mit jlibrtp, die bekommt den job getan.
Ich weiß nicht, etwas über MediaCodec oder MediaExtractor noch, aber ich bin ziemlich vertraut mit MediaRecorder und erfolgreich umgesetzt haben einem RTSP-server, basierend auf SpyDroid fängt H264/AMRNB-Ausgabe von MediaRecorder. Die grundlegende Idee ist, dass der code erstellt eine lokale socket-paar und verwendet setOutputFile der MediaRecorder um die Ausgabe in eine der Steckdosen im paar. Dann liest das Programm die video-oder audio-stream aus der anderen Buchse, analysiert Sie in Pakete, und dann schließt jedes Paket in ein oder mehrere RTP-Pakete, die gesendet werden über UDP.
Es ist wahr, dass MediaRecorder fügt die MOOV-Header, nachdem es fertig ist, aber das ist kein problem, wenn man hilft H264 video im RTP-format. Im Grunde gibt es eine "mdat" header am Anfang des video-Streams. Es hat 4 bytes für die Länge des header, gefolgt von den 4 bytes "mdat". Lesen Sie die Länge, um herauszufinden, wie lang der header ist, stellen Sie sicher, dass es die mdat-header, und dann überspringen Sie den rest der header-Daten. Von da an, Sie bekommen einen stream von NAL-Einheiten, die beginnen mit 4 bytes für die Länge der Einheit. Kleine NAL-Einheiten gesendet werden können, in einem einzigen RTP-Paket ist, und größere Einheiten kaputt zu bekommen in FU-Pakete. Für RTSP, werden Sie auch brauchen, um zu dienen ein SDP-header, der beschreibt das streamen. SpyDroid berechnet die info im SDP-header durch das schreiben eine sehr kurze Film-Datei, und liest dann diese Datei zum extrahieren der MOOV-header vom Ende. Meine app verwendet immer die gleiche Größe, das format und die bitrate, so dass ich nur dazu dienen, einen statischen string:
Das ist mein header für 640x480x10fps, H264-video, mit 8000/16/1 AMRNB-audio.
Eins kann ich Sie warnen: Wenn Sie MediaRecorder, Ihr Album Vorhören callback wird nie aufgerufen. Das funktioniert nur im camera-Modus nicht, wenn Sie ein video aufnehmen. Ich habe nicht in der Lage zu finden, eine Möglichkeit, den Zugriff auf das Vorschau-Bild im unkomprimierten format, während der video-Aufnahme ist.
Empfehle ich auf der Suche über den code für SpyDroid. Es dauert einige Graben, aber ich Wette was Sie wollen, ist schon drin.
Was Sie planen, ist auf jeden Fall machbar. Sie können sich registrieren, eine Kamera.PreviewCallback, welche die Bild-Daten, und stellt es in den MediaCodec. Lesen Sie die Ausgabe und senden Sie es als RTP. Im Allgemeinen ist es einfach, aber es gibt diverse Fallstricke, wie undokumentierte Farbräume und verschiedene MediaCodec Verhalten auf verschiedenen Geräten, aber es ist definitiv möglich.